Back to index

cell-binutils  2.17cvs20070401
tc-m68hc11.c
Go to the documentation of this file.
00001 /* tc-m68hc11.c -- Assembler code for the Motorola 68HC11 & 68HC12.
00002    Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
00003    Free Software Foundation, Inc.
00004    Written by Stephane Carrez (stcarrez@nerim.fr)
00005 
00006    This file is part of GAS, the GNU Assembler.
00007 
00008    GAS is free software; you can redistribute it and/or modify
00009    it under the terms of the GNU General Public License as published by
00010    the Free Software Foundation; either version 2, or (at your option)
00011    any later version.
00012 
00013    GAS is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016    GNU General Public License for more details.
00017 
00018    You should have received a copy of the GNU General Public License
00019    along with GAS; see the file COPYING.  If not, write to
00020    the Free Software Foundation, 51 Franklin Street - Fifth Floor,
00021    Boston, MA 02110-1301, USA.  */
00022 
00023 #include "as.h"
00024 #include "safe-ctype.h"
00025 #include "subsegs.h"
00026 #include "opcode/m68hc11.h"
00027 #include "dwarf2dbg.h"
00028 #include "elf/m68hc11.h"
00029 
00030 const char comment_chars[] = ";!";
00031 const char line_comment_chars[] = "#*";
00032 const char line_separator_chars[] = "";
00033 
00034 const char EXP_CHARS[] = "eE";
00035 const char FLT_CHARS[] = "dD";
00036 
00037 #define STATE_CONDITIONAL_BRANCH   (1)
00038 #define STATE_PC_RELATIVE          (2)
00039 #define STATE_INDEXED_OFFSET            (3)
00040 #define STATE_INDEXED_PCREL             (4)
00041 #define STATE_XBCC_BRANCH               (5)
00042 #define STATE_CONDITIONAL_BRANCH_6812     (6)
00043 
00044 #define STATE_BYTE                 (0)
00045 #define STATE_BITS5                     (0)
00046 #define STATE_WORD                 (1)
00047 #define STATE_BITS9                     (1)
00048 #define STATE_LONG                 (2)
00049 #define STATE_BITS16                    (2)
00050 #define STATE_UNDF                 (3)    /* Symbol undefined in pass1 */
00051 
00052 /* This macro has no side-effects.  */
00053 #define ENCODE_RELAX(what,length) (((what) << 2) + (length))
00054 #define RELAX_STATE(s) ((s) >> 2)
00055 #define RELAX_LENGTH(s) ((s) & 3)
00056 
00057 #define IS_OPCODE(C1,C2)        (((C1) & 0x0FF) == ((C2) & 0x0FF))
00058 
00059 /* This table describes how you change sizes for the various types of variable
00060    size expressions.  This version only supports two kinds.  */
00061 
00062 /* The fields are:
00063    How far Forward this mode will reach.
00064    How far Backward this mode will reach.
00065    How many bytes this mode will add to the size of the frag.
00066    Which mode to go to if the offset won't fit in this one.  */
00067 
00068 relax_typeS md_relax_table[] = {
00069   {1, 1, 0, 0},                    /* First entries aren't used.  */
00070   {1, 1, 0, 0},                    /* For no good reason except.  */
00071   {1, 1, 0, 0},                    /* that the VAX doesn't either.  */
00072   {1, 1, 0, 0},
00073 
00074   /* Relax for bcc <L>.
00075      These insns are translated into b!cc +3 jmp L.  */
00076   {(127), (-128), 0, ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_WORD)},
00077   {0, 0, 3, 0},
00078   {1, 1, 0, 0},
00079   {1, 1, 0, 0},
00080 
00081   /* Relax for bsr <L> and bra <L>.
00082      These insns are translated into jsr and jmp.  */
00083   {(127), (-128), 0, ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD)},
00084   {0, 0, 1, 0},
00085   {1, 1, 0, 0},
00086   {1, 1, 0, 0},
00087 
00088   /* Relax for indexed offset: 5-bits, 9-bits, 16-bits.  */
00089   {(15), (-16), 0, ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9)},
00090   {(255), (-256), 1, ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16)},
00091   {0, 0, 2, 0},
00092   {1, 1, 0, 0},
00093 
00094   /* Relax for PC relative offset: 5-bits, 9-bits, 16-bits.
00095      For the 9-bit case, there will be a -1 correction to take into
00096      account the new byte that's why the range is -255..256.  */
00097   {(15), (-16), 0, ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS9)},
00098   {(256), (-255), 1, ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS16)},
00099   {0, 0, 2, 0},
00100   {1, 1, 0, 0},
00101 
00102   /* Relax for dbeq/ibeq/tbeq r,<L>:
00103      These insns are translated into db!cc +3 jmp L.  */
00104   {(255), (-256), 0, ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_WORD)},
00105   {0, 0, 3, 0},
00106   {1, 1, 0, 0},
00107   {1, 1, 0, 0},
00108 
00109   /* Relax for bcc <L> on 68HC12.
00110      These insns are translated into lbcc <L>.  */
00111   {(127), (-128), 0, ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_WORD)},
00112   {0, 0, 2, 0},
00113   {1, 1, 0, 0},
00114   {1, 1, 0, 0},
00115 
00116 };
00117 
00118 /* 68HC11 and 68HC12 registers.  They are numbered according to the 68HC12.  */
00119 typedef enum register_id {
00120   REG_NONE = -1,
00121   REG_A = 0,
00122   REG_B = 1,
00123   REG_CCR = 2,
00124   REG_D = 4,
00125   REG_X = 5,
00126   REG_Y = 6,
00127   REG_SP = 7,
00128   REG_PC = 8
00129 } register_id;
00130 
00131 typedef struct operand {
00132   expressionS exp;
00133   register_id reg1;
00134   register_id reg2;
00135   int mode;
00136 } operand;
00137 
00138 struct m68hc11_opcode_def {
00139   long format;
00140   int min_operands;
00141   int max_operands;
00142   int nb_modes;
00143   int used;
00144   struct m68hc11_opcode *opcode;
00145 };
00146 
00147 static struct m68hc11_opcode_def *m68hc11_opcode_defs = 0;
00148 static int m68hc11_nb_opcode_defs = 0;
00149 
00150 typedef struct alias {
00151   const char *name;
00152   const char *alias;
00153 } alias;
00154 
00155 static alias alias_opcodes[] = {
00156   {"cpd", "cmpd"},
00157   {"cpx", "cmpx"},
00158   {"cpy", "cmpy"},
00159   {0, 0}
00160 };
00161 
00162 /* Local functions.  */
00163 static register_id reg_name_search (char *);
00164 static register_id register_name (void);
00165 static int cmp_opcode (struct m68hc11_opcode *, struct m68hc11_opcode *);
00166 static char *print_opcode_format (struct m68hc11_opcode *, int);
00167 static char *skip_whites (char *);
00168 static int check_range (long, int);
00169 static void print_opcode_list (void);
00170 static void get_default_target (void);
00171 static void print_insn_format (char *);
00172 static int get_operand (operand *, int, long);
00173 static void fixup8 (expressionS *, int, int);
00174 static void fixup16 (expressionS *, int, int);
00175 static void fixup24 (expressionS *, int, int);
00176 static unsigned char convert_branch (unsigned char);
00177 static char *m68hc11_new_insn (int);
00178 static void build_dbranch_insn (struct m68hc11_opcode *,
00179                                 operand *, int, int);
00180 static int build_indexed_byte (operand *, int, int);
00181 static int build_reg_mode (operand *, int);
00182 
00183 static struct m68hc11_opcode *find (struct m68hc11_opcode_def *,
00184                                     operand *, int);
00185 static struct m68hc11_opcode *find_opcode (struct m68hc11_opcode_def *,
00186                                            operand *, int *);
00187 static void build_jump_insn (struct m68hc11_opcode *, operand *, int, int);
00188 static void build_insn (struct m68hc11_opcode *, operand *, int);
00189 static int relaxable_symbol (symbolS *);
00190 
00191 /* Pseudo op to indicate a relax group.  */
00192 static void s_m68hc11_relax (int);
00193 
00194 /* Pseudo op to control the ELF flags.  */
00195 static void s_m68hc11_mode (int);
00196 
00197 /* Mark the symbols with STO_M68HC12_FAR to indicate the functions
00198    are using 'rtc' for returning.  It is necessary to use 'call'
00199    to invoke them.  This is also used by the debugger to correctly
00200    find the stack frame.  */
00201 static void s_m68hc11_mark_symbol (int);
00202 
00203 /* Controls whether relative branches can be turned into long branches.
00204    When the relative offset is too large, the insn are changed:
00205     bra -> jmp
00206     bsr -> jsr
00207     bcc -> b!cc +3
00208            jmp L
00209     dbcc -> db!cc +3
00210             jmp L
00211 
00212   Setting the flag forbidds this.  */
00213 static short flag_fixed_branches = 0;
00214 
00215 /* Force to use long jumps (absolute) instead of relative branches.  */
00216 static short flag_force_long_jumps = 0;
00217 
00218 /* Change the direct addressing mode into an absolute addressing mode
00219    when the insn does not support direct addressing.
00220    For example, "clr *ZD0" is normally not possible and is changed
00221    into "clr ZDO".  */
00222 static short flag_strict_direct_addressing = 1;
00223 
00224 /* When an opcode has invalid operand, print out the syntax of the opcode
00225    to stderr.  */
00226 static short flag_print_insn_syntax = 0;
00227 
00228 /* Dumps the list of instructions with syntax and then exit:
00229    1 -> Only dumps the list (sorted by name)
00230    2 -> Generate an example (or test) that can be compiled.  */
00231 static short flag_print_opcodes = 0;
00232 
00233 /* Opcode hash table.  */
00234 static struct hash_control *m68hc11_hash;
00235 
00236 /* Current cpu (either cpu6811 or cpu6812).  This is determined automagically
00237    by 'get_default_target' by looking at default BFD vector.  This is overridden
00238    with the -m<cpu> option.  */
00239 static int current_architecture = 0;
00240 
00241 /* Default cpu determined by 'get_default_target'.  */
00242 static const char *default_cpu;
00243 
00244 /* Number of opcodes in the sorted table (filtered by current cpu).  */
00245 static int num_opcodes;
00246 
00247 /* The opcodes sorted by name and filtered by current cpu.  */
00248 static struct m68hc11_opcode *m68hc11_sorted_opcodes;
00249 
00250 /* ELF flags to set in the output file header.  */
00251 static int elf_flags = E_M68HC11_F64;
00252 
00253 /* These are the machine dependent pseudo-ops.  These are included so
00254    the assembler can work on the output from the SUN C compiler, which
00255    generates these.  */
00256 
00257 /* This table describes all the machine specific pseudo-ops the assembler
00258    has to support.  The fields are:
00259    pseudo-op name without dot
00260    function to call to execute this pseudo-op
00261    Integer arg to pass to the function.  */
00262 const pseudo_typeS md_pseudo_table[] = {
00263   /* The following pseudo-ops are supported for MRI compatibility.  */
00264   {"fcb", cons, 1},
00265   {"fdb", cons, 2},
00266   {"fcc", stringer, 1},
00267   {"rmb", s_space, 0},
00268 
00269   /* Motorola ALIS.  */
00270   {"xrefb", s_ignore, 0}, /* Same as xref  */
00271 
00272   /* Gcc driven relaxation.  */
00273   {"relax", s_m68hc11_relax, 0},
00274 
00275   /* .mode instruction (ala SH).  */
00276   {"mode", s_m68hc11_mode, 0},
00277 
00278   /* .far instruction.  */
00279   {"far", s_m68hc11_mark_symbol, STO_M68HC12_FAR},
00280 
00281   /* .interrupt instruction.  */
00282   {"interrupt", s_m68hc11_mark_symbol, STO_M68HC12_INTERRUPT},
00283 
00284   {0, 0, 0}
00285 };
00286 
00287 /* Options and initialization.  */
00288 
00289 const char *md_shortopts = "Sm:";
00290 
00291 struct option md_longopts[] = {
00292 #define OPTION_FORCE_LONG_BRANCH (OPTION_MD_BASE)
00293   {"force-long-branches", no_argument, NULL, OPTION_FORCE_LONG_BRANCH},
00294   {"force-long-branchs", no_argument, NULL, OPTION_FORCE_LONG_BRANCH}, /* Misspelt version kept for backwards compatibility.  */
00295 
00296 #define OPTION_SHORT_BRANCHES     (OPTION_MD_BASE + 1)
00297   {"short-branches", no_argument, NULL, OPTION_SHORT_BRANCHES},
00298   {"short-branchs", no_argument, NULL, OPTION_SHORT_BRANCHES}, /* Misspelt version kept for backwards compatibility.  */
00299 
00300 #define OPTION_STRICT_DIRECT_MODE  (OPTION_MD_BASE + 2)
00301   {"strict-direct-mode", no_argument, NULL, OPTION_STRICT_DIRECT_MODE},
00302 
00303 #define OPTION_PRINT_INSN_SYNTAX  (OPTION_MD_BASE + 3)
00304   {"print-insn-syntax", no_argument, NULL, OPTION_PRINT_INSN_SYNTAX},
00305 
00306 #define OPTION_PRINT_OPCODES  (OPTION_MD_BASE + 4)
00307   {"print-opcodes", no_argument, NULL, OPTION_PRINT_OPCODES},
00308 
00309 #define OPTION_GENERATE_EXAMPLE  (OPTION_MD_BASE + 5)
00310   {"generate-example", no_argument, NULL, OPTION_GENERATE_EXAMPLE},
00311 
00312 #define OPTION_MSHORT  (OPTION_MD_BASE + 6)
00313   {"mshort", no_argument, NULL, OPTION_MSHORT},
00314 
00315 #define OPTION_MLONG  (OPTION_MD_BASE + 7)
00316   {"mlong", no_argument, NULL, OPTION_MLONG},
00317 
00318 #define OPTION_MSHORT_DOUBLE  (OPTION_MD_BASE + 8)
00319   {"mshort-double", no_argument, NULL, OPTION_MSHORT_DOUBLE},
00320 
00321 #define OPTION_MLONG_DOUBLE  (OPTION_MD_BASE + 9)
00322   {"mlong-double", no_argument, NULL, OPTION_MLONG_DOUBLE},
00323 
00324   {NULL, no_argument, NULL, 0}
00325 };
00326 size_t md_longopts_size = sizeof (md_longopts);
00327 
00328 /* Get the target cpu for the assembler.  This is based on the configure
00329    options and on the -m68hc11/-m68hc12 option.  If no option is specified,
00330    we must get the default.  */
00331 const char *
00332 m68hc11_arch_format (void)
00333 {
00334   get_default_target ();
00335   if (current_architecture & cpu6811)
00336     return "elf32-m68hc11";
00337   else
00338     return "elf32-m68hc12";
00339 }
00340 
00341 enum bfd_architecture
00342 m68hc11_arch (void)
00343 {
00344   get_default_target ();
00345   if (current_architecture & cpu6811)
00346     return bfd_arch_m68hc11;
00347   else
00348     return bfd_arch_m68hc12;
00349 }
00350 
00351 int
00352 m68hc11_mach (void)
00353 {
00354   return 0;
00355 }
00356 
00357 /* Listing header selected according to cpu.  */
00358 const char *
00359 m68hc11_listing_header (void)
00360 {
00361   if (current_architecture & cpu6811)
00362     return "M68HC11 GAS ";
00363   else
00364     return "M68HC12 GAS ";
00365 }
00366 
00367 void
00368 md_show_usage (FILE *stream)
00369 {
00370   get_default_target ();
00371   fprintf (stream, _("\
00372 Motorola 68HC11/68HC12/68HCS12 options:\n\
00373   -m68hc11 | -m68hc12 |\n\
00374   -m68hcs12               specify the processor [default %s]\n\
00375   -mshort                 use 16-bit int ABI (default)\n\
00376   -mlong                  use 32-bit int ABI\n\
00377   -mshort-double          use 32-bit double ABI\n\
00378   -mlong-double           use 64-bit double ABI (default)\n\
00379   --force-long-branches   always turn relative branches into absolute ones\n\
00380   -S,--short-branches     do not turn relative branches into absolute ones\n\
00381                           when the offset is out of range\n\
00382   --strict-direct-mode    do not turn the direct mode into extended mode\n\
00383                           when the instruction does not support direct mode\n\
00384   --print-insn-syntax     print the syntax of instruction in case of error\n\
00385   --print-opcodes         print the list of instructions with syntax\n\
00386   --generate-example      generate an example of each instruction\n\
00387                           (used for testing)\n"), default_cpu);
00388 
00389 }
00390 
00391 /* Try to identify the default target based on the BFD library.  */
00392 static void
00393 get_default_target (void)
00394 {
00395   const bfd_target *target;
00396   bfd abfd;
00397 
00398   if (current_architecture != 0)
00399     return;
00400 
00401   default_cpu = "unknown";
00402   target = bfd_find_target (0, &abfd);
00403   if (target && target->name)
00404     {
00405       if (strcmp (target->name, "elf32-m68hc12") == 0)
00406        {
00407          current_architecture = cpu6812;
00408          default_cpu = "m68hc12";
00409        }
00410       else if (strcmp (target->name, "elf32-m68hc11") == 0)
00411        {
00412          current_architecture = cpu6811;
00413          default_cpu = "m68hc11";
00414        }
00415       else
00416        {
00417          as_bad (_("Default target `%s' is not supported."), target->name);
00418        }
00419     }
00420 }
00421 
00422 void
00423 m68hc11_print_statistics (FILE *file)
00424 {
00425   int i;
00426   struct m68hc11_opcode_def *opc;
00427 
00428   hash_print_statistics (file, "opcode table", m68hc11_hash);
00429 
00430   opc = m68hc11_opcode_defs;
00431   if (opc == 0 || m68hc11_nb_opcode_defs == 0)
00432     return;
00433 
00434   /* Dump the opcode statistics table.  */
00435   fprintf (file, _("Name   # Modes  Min ops  Max ops  Modes mask  # Used\n"));
00436   for (i = 0; i < m68hc11_nb_opcode_defs; i++, opc++)
00437     {
00438       fprintf (file, "%-7.7s  %5d  %7d  %7d  0x%08lx  %7d\n",
00439               opc->opcode->name,
00440               opc->nb_modes,
00441               opc->min_operands, opc->max_operands, opc->format, opc->used);
00442     }
00443 }
00444 
00445 int
00446 md_parse_option (int c, char *arg)
00447 {
00448   get_default_target ();
00449   switch (c)
00450     {
00451       /* -S means keep external to 2 bit offset rather than 16 bit one.  */
00452     case OPTION_SHORT_BRANCHES:
00453     case 'S':
00454       flag_fixed_branches = 1;
00455       break;
00456 
00457     case OPTION_FORCE_LONG_BRANCH:
00458       flag_force_long_jumps = 1;
00459       break;
00460 
00461     case OPTION_PRINT_INSN_SYNTAX:
00462       flag_print_insn_syntax = 1;
00463       break;
00464 
00465     case OPTION_PRINT_OPCODES:
00466       flag_print_opcodes = 1;
00467       break;
00468 
00469     case OPTION_STRICT_DIRECT_MODE:
00470       flag_strict_direct_addressing = 0;
00471       break;
00472 
00473     case OPTION_GENERATE_EXAMPLE:
00474       flag_print_opcodes = 2;
00475       break;
00476 
00477     case OPTION_MSHORT:
00478       elf_flags &= ~E_M68HC11_I32;
00479       break;
00480 
00481     case OPTION_MLONG:
00482       elf_flags |= E_M68HC11_I32;
00483       break;
00484 
00485     case OPTION_MSHORT_DOUBLE:
00486       elf_flags &= ~E_M68HC11_F64;
00487       break;
00488 
00489     case OPTION_MLONG_DOUBLE:
00490       elf_flags |= E_M68HC11_F64;
00491       break;
00492 
00493     case 'm':
00494       if (strcasecmp (arg, "68hc11") == 0)
00495        current_architecture = cpu6811;
00496       else if (strcasecmp (arg, "68hc12") == 0)
00497        current_architecture = cpu6812;
00498       else if (strcasecmp (arg, "68hcs12") == 0)
00499        current_architecture = cpu6812 | cpu6812s;
00500       else
00501        as_bad (_("Option `%s' is not recognized."), arg);
00502       break;
00503 
00504     default:
00505       return 0;
00506     }
00507 
00508   return 1;
00509 }
00510 
00511 symbolS *
00512 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
00513 {
00514   return 0;
00515 }
00516 
00517 /* Equal to MAX_PRECISION in atof-ieee.c.  */
00518 #define MAX_LITTLENUMS 6
00519 
00520 /* Turn a string in input_line_pointer into a floating point constant
00521    of type TYPE, and store the appropriate bytes in *LITP.  The number
00522    of LITTLENUMS emitted is stored in *SIZEP.  An error message is
00523    returned, or NULL on OK.  */
00524 char *
00525 md_atof (int type, char *litP, int *sizeP)
00526 {
00527   int prec;
00528   LITTLENUM_TYPE words[MAX_LITTLENUMS];
00529   LITTLENUM_TYPE *wordP;
00530   char *t;
00531 
00532   switch (type)
00533     {
00534     case 'f':
00535     case 'F':
00536     case 's':
00537     case 'S':
00538       prec = 2;
00539       break;
00540 
00541     case 'd':
00542     case 'D':
00543     case 'r':
00544     case 'R':
00545       prec = 4;
00546       break;
00547 
00548     case 'x':
00549     case 'X':
00550       prec = 6;
00551       break;
00552 
00553     case 'p':
00554     case 'P':
00555       prec = 6;
00556       break;
00557 
00558     default:
00559       *sizeP = 0;
00560       return _("Bad call to MD_ATOF()");
00561     }
00562   t = atof_ieee (input_line_pointer, type, words);
00563   if (t)
00564     input_line_pointer = t;
00565 
00566   *sizeP = prec * sizeof (LITTLENUM_TYPE);
00567   for (wordP = words; prec--;)
00568     {
00569       md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE));
00570       litP += sizeof (LITTLENUM_TYPE);
00571     }
00572   return 0;
00573 }
00574 
00575 valueT
00576 md_section_align (asection *seg, valueT addr)
00577 {
00578   int align = bfd_get_section_alignment (stdoutput, seg);
00579   return ((addr + (1 << align) - 1) & (-1 << align));
00580 }
00581 
00582 static int
00583 cmp_opcode (struct m68hc11_opcode *op1, struct m68hc11_opcode *op2)
00584 {
00585   return strcmp (op1->name, op2->name);
00586 }
00587 
00588 #define IS_CALL_SYMBOL(MODE) \
00589 (((MODE) & (M6812_OP_PAGE|M6811_OP_IND16)) \
00590   == ((M6812_OP_PAGE|M6811_OP_IND16)))
00591 
00592 /* Initialize the assembler.  Create the opcode hash table
00593    (sorted on the names) with the M6811 opcode table
00594    (from opcode library).  */
00595 void
00596 md_begin (void)
00597 {
00598   char *prev_name = "";
00599   struct m68hc11_opcode *opcodes;
00600   struct m68hc11_opcode_def *opc = 0;
00601   int i, j;
00602 
00603   get_default_target ();
00604 
00605   m68hc11_hash = hash_new ();
00606 
00607   /* Get a writable copy of the opcode table and sort it on the names.  */
00608   opcodes = (struct m68hc11_opcode *) xmalloc (m68hc11_num_opcodes *
00609                                           sizeof (struct
00610                                                  m68hc11_opcode));
00611   m68hc11_sorted_opcodes = opcodes;
00612   num_opcodes = 0;
00613   for (i = 0; i < m68hc11_num_opcodes; i++)
00614     {
00615       if (m68hc11_opcodes[i].arch & current_architecture)
00616        {
00617          opcodes[num_opcodes] = m68hc11_opcodes[i];
00618          if (opcodes[num_opcodes].name[0] == 'b'
00619              && opcodes[num_opcodes].format & M6811_OP_JUMP_REL
00620              && !(opcodes[num_opcodes].format & M6811_OP_BITMASK))
00621            {
00622              num_opcodes++;
00623              opcodes[num_opcodes] = m68hc11_opcodes[i];
00624            }
00625          num_opcodes++;
00626          for (j = 0; alias_opcodes[j].name != 0; j++)
00627            if (strcmp (m68hc11_opcodes[i].name, alias_opcodes[j].name) == 0)
00628              {
00629               opcodes[num_opcodes] = m68hc11_opcodes[i];
00630               opcodes[num_opcodes].name = alias_opcodes[j].alias;
00631               num_opcodes++;
00632               break;
00633              }
00634        }
00635     }
00636   qsort (opcodes, num_opcodes, sizeof (struct m68hc11_opcode),
00637          (int (*) (const void*, const void*)) cmp_opcode);
00638 
00639   opc = (struct m68hc11_opcode_def *)
00640     xmalloc (num_opcodes * sizeof (struct m68hc11_opcode_def));
00641   m68hc11_opcode_defs = opc--;
00642 
00643   /* Insert unique names into hash table.  The M6811 instruction set
00644      has several identical opcode names that have different opcodes based
00645      on the operands.  This hash table then provides a quick index to
00646      the first opcode with a particular name in the opcode table.  */
00647   for (i = 0; i < num_opcodes; i++, opcodes++)
00648     {
00649       int expect;
00650 
00651       if (strcmp (prev_name, opcodes->name))
00652        {
00653          prev_name = (char *) opcodes->name;
00654 
00655          opc++;
00656          opc->format = 0;
00657          opc->min_operands = 100;
00658          opc->max_operands = 0;
00659          opc->nb_modes = 0;
00660          opc->opcode = opcodes;
00661          opc->used = 0;
00662          hash_insert (m68hc11_hash, opcodes->name, opc);
00663        }
00664       opc->nb_modes++;
00665       opc->format |= opcodes->format;
00666 
00667       /* See how many operands this opcode needs.  */
00668       expect = 0;
00669       if (opcodes->format & M6811_OP_MASK)
00670        expect++;
00671       if (opcodes->format & M6811_OP_BITMASK)
00672        expect++;
00673       if (opcodes->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
00674        expect++;
00675       if (opcodes->format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2))
00676        expect++;
00677       /* Special case for call instruction.  */
00678       if ((opcodes->format & M6812_OP_PAGE)
00679           && !(opcodes->format & M6811_OP_IND16))
00680         expect++;
00681 
00682       if (expect < opc->min_operands)
00683        opc->min_operands = expect;
00684       if (IS_CALL_SYMBOL (opcodes->format))
00685          expect++;
00686       if (expect > opc->max_operands)
00687        opc->max_operands = expect;
00688     }
00689   opc++;
00690   m68hc11_nb_opcode_defs = opc - m68hc11_opcode_defs;
00691 
00692   if (flag_print_opcodes)
00693     {
00694       print_opcode_list ();
00695       exit (EXIT_SUCCESS);
00696     }
00697 }
00698 
00699 void
00700 m68hc11_init_after_args (void)
00701 {
00702 }
00703 
00704 /* Builtin help.  */
00705 
00706 /* Return a string that represents the operand format for the instruction.
00707    When example is true, this generates an example of operand.  This is used
00708    to give an example and also to generate a test.  */
00709 static char *
00710 print_opcode_format (struct m68hc11_opcode *opcode, int example)
00711 {
00712   static char buf[128];
00713   int format = opcode->format;
00714   char *p;
00715 
00716   p = buf;
00717   buf[0] = 0;
00718   if (format & M6811_OP_IMM8)
00719     {
00720       if (example)
00721        sprintf (p, "#%d", rand () & 0x0FF);
00722       else
00723        strcpy (p, _("#<imm8>"));
00724       p = &p[strlen (p)];
00725     }
00726 
00727   if (format & M6811_OP_IMM16)
00728     {
00729       if (example)
00730        sprintf (p, "#%d", rand () & 0x0FFFF);
00731       else
00732        strcpy (p, _("#<imm16>"));
00733       p = &p[strlen (p)];
00734     }
00735 
00736   if (format & M6811_OP_IX)
00737     {
00738       if (example)
00739        sprintf (p, "%d,X", rand () & 0x0FF);
00740       else
00741        strcpy (p, _("<imm8>,X"));
00742       p = &p[strlen (p)];
00743     }
00744 
00745   if (format & M6811_OP_IY)
00746     {
00747       if (example)
00748        sprintf (p, "%d,X", rand () & 0x0FF);
00749       else
00750        strcpy (p, _("<imm8>,X"));
00751       p = &p[strlen (p)];
00752     }
00753 
00754   if (format & M6812_OP_IDX)
00755     {
00756       if (example)
00757        sprintf (p, "%d,X", rand () & 0x0FF);
00758       else
00759        strcpy (p, "n,r");
00760       p = &p[strlen (p)];
00761     }
00762 
00763   if (format & M6812_OP_PAGE)
00764     {
00765       if (example)
00766        sprintf (p, ", %d", rand () & 0x0FF);
00767       else
00768        strcpy (p, ", <page>");
00769       p = &p[strlen (p)];
00770     }
00771 
00772   if (format & M6811_OP_DIRECT)
00773     {
00774       if (example)
00775        sprintf (p, "*Z%d", rand () & 0x0FF);
00776       else
00777        strcpy (p, _("*<abs8>"));
00778       p = &p[strlen (p)];
00779     }
00780 
00781   if (format & M6811_OP_BITMASK)
00782     {
00783       if (buf[0])
00784        *p++ = ' ';
00785 
00786       if (example)
00787        sprintf (p, "#$%02x", rand () & 0x0FF);
00788       else
00789        strcpy (p, _("#<mask>"));
00790 
00791       p = &p[strlen (p)];
00792       if (format & M6811_OP_JUMP_REL)
00793        *p++ = ' ';
00794     }
00795 
00796   if (format & M6811_OP_IND16)
00797     {
00798       if (example)
00799        sprintf (p, _("symbol%d"), rand () & 0x0FF);
00800       else
00801        strcpy (p, _("<abs>"));
00802 
00803       p = &p[strlen (p)];
00804     }
00805 
00806   if (format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
00807     {
00808       if (example)
00809        {
00810          if (format & M6811_OP_BITMASK)
00811            {
00812              sprintf (p, ".+%d", rand () & 0x7F);
00813            }
00814          else
00815            {
00816              sprintf (p, "L%d", rand () & 0x0FF);
00817            }
00818        }
00819       else
00820        strcpy (p, _("<label>"));
00821     }
00822 
00823   return buf;
00824 }
00825 
00826 /* Prints the list of instructions with the possible operands.  */
00827 static void
00828 print_opcode_list (void)
00829 {
00830   int i;
00831   char *prev_name = "";
00832   struct m68hc11_opcode *opcodes;
00833   int example = flag_print_opcodes == 2;
00834 
00835   if (example)
00836     printf (_("# Example of `%s' instructions\n\t.sect .text\n_start:\n"),
00837            default_cpu);
00838 
00839   opcodes = m68hc11_sorted_opcodes;
00840 
00841   /* Walk the list sorted on names (by md_begin).  We only report
00842      one instruction per line, and we collect the different operand
00843      formats.  */
00844   for (i = 0; i < num_opcodes; i++, opcodes++)
00845     {
00846       char *fmt = print_opcode_format (opcodes, example);
00847 
00848       if (example)
00849        {
00850          printf ("L%d:\t", i);
00851          printf ("%s %s\n", opcodes->name, fmt);
00852        }
00853       else
00854        {
00855          if (strcmp (prev_name, opcodes->name))
00856            {
00857              if (i > 0)
00858               printf ("\n");
00859 
00860              printf ("%-5.5s ", opcodes->name);
00861              prev_name = (char *) opcodes->name;
00862            }
00863          if (fmt[0])
00864            printf ("  [%s]", fmt);
00865        }
00866     }
00867   printf ("\n");
00868 }
00869 
00870 /* Print the instruction format.  This operation is called when some
00871    instruction is not correct.  Instruction format is printed as an
00872    error message.  */
00873 static void
00874 print_insn_format (char *name)
00875 {
00876   struct m68hc11_opcode_def *opc;
00877   struct m68hc11_opcode *opcode;
00878   char buf[128];
00879 
00880   opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash, name);
00881   if (opc == NULL)
00882     {
00883       as_bad (_("Instruction `%s' is not recognized."), name);
00884       return;
00885     }
00886   opcode = opc->opcode;
00887 
00888   as_bad (_("Instruction formats for `%s':"), name);
00889   do
00890     {
00891       char *fmt;
00892 
00893       fmt = print_opcode_format (opcode, 0);
00894       sprintf (buf, "\t%-5.5s %s", opcode->name, fmt);
00895 
00896       as_bad ("%s", buf);
00897       opcode++;
00898     }
00899   while (strcmp (opcode->name, name) == 0);
00900 }
00901 
00902 /* Analysis of 68HC11 and 68HC12 operands.  */
00903 
00904 /* reg_name_search() finds the register number given its name.
00905    Returns the register number or REG_NONE on failure.  */
00906 static register_id
00907 reg_name_search (char *name)
00908 {
00909   if (strcasecmp (name, "x") == 0 || strcasecmp (name, "ix") == 0)
00910     return REG_X;
00911   if (strcasecmp (name, "y") == 0 || strcasecmp (name, "iy") == 0)
00912     return REG_Y;
00913   if (strcasecmp (name, "a") == 0)
00914     return REG_A;
00915   if (strcasecmp (name, "b") == 0)
00916     return REG_B;
00917   if (strcasecmp (name, "d") == 0)
00918     return REG_D;
00919   if (strcasecmp (name, "sp") == 0)
00920     return REG_SP;
00921   if (strcasecmp (name, "pc") == 0)
00922     return REG_PC;
00923   if (strcasecmp (name, "ccr") == 0)
00924     return REG_CCR;
00925 
00926   return REG_NONE;
00927 }
00928 
00929 static char *
00930 skip_whites (char *p)
00931 {
00932   while (*p == ' ' || *p == '\t')
00933     p++;
00934 
00935   return p;
00936 }
00937 
00938 /* Check the string at input_line_pointer
00939    to see if it is a valid register name.  */
00940 static register_id
00941 register_name (void)
00942 {
00943   register_id reg_number;
00944   char c, *p = input_line_pointer;
00945 
00946   if (!is_name_beginner (*p++))
00947     return REG_NONE;
00948 
00949   while (is_part_of_name (*p++))
00950     continue;
00951 
00952   c = *--p;
00953   if (c)
00954     *p++ = 0;
00955 
00956   /* Look to see if it's in the register table.  */
00957   reg_number = reg_name_search (input_line_pointer);
00958   if (reg_number != REG_NONE)
00959     {
00960       if (c)
00961        *--p = c;
00962 
00963       input_line_pointer = p;
00964       return reg_number;
00965     }
00966   if (c)
00967     *--p = c;
00968 
00969   return reg_number;
00970 }
00971 #define M6811_OP_CALL_ADDR    0x00800000
00972 #define M6811_OP_PAGE_ADDR    0x04000000
00973 
00974 /* Parse a string of operands and return an array of expressions.
00975 
00976    Operand      mode[0]         mode[1]       exp[0]       exp[1]
00977    #n           M6811_OP_IMM16  -             O_*
00978    *<exp>       M6811_OP_DIRECT -             O_*
00979    .{+-}<exp>   M6811_OP_JUMP_REL -           O_*
00980    <exp>        M6811_OP_IND16  -             O_*
00981    ,r N,r       M6812_OP_IDX    M6812_OP_REG  O_constant   O_register
00982    n,-r         M6812_PRE_DEC   M6812_OP_REG  O_constant   O_register
00983    n,+r         M6812_PRE_INC   " "
00984    n,r-         M6812_POST_DEC  " "
00985    n,r+         M6812_POST_INC  " "
00986    A,r B,r D,r  M6811_OP_REG    M6812_OP_REG  O_register   O_register
00987    [D,r]        M6811_OP_D_IDX  M6812_OP_REG  O_register   O_register
00988    [n,r]        M6811_OP_D_IDX_2 M6812_OP_REG  O_constant   O_register  */
00989 static int
00990 get_operand (operand *oper, int which, long opmode)
00991 {
00992   char *p = input_line_pointer;
00993   int mode;
00994   register_id reg;
00995 
00996   oper->exp.X_op = O_absent;
00997   oper->reg1 = REG_NONE;
00998   oper->reg2 = REG_NONE;
00999   mode = M6811_OP_NONE;
01000 
01001   p = skip_whites (p);
01002 
01003   if (*p == 0 || *p == '\n' || *p == '\r')
01004     {
01005       input_line_pointer = p;
01006       return 0;
01007     }
01008 
01009   if (*p == '*' && (opmode & (M6811_OP_DIRECT | M6811_OP_IND16)))
01010     {
01011       mode = M6811_OP_DIRECT;
01012       p++;
01013     }
01014   else if (*p == '#')
01015     {
01016       if (!(opmode & (M6811_OP_IMM8 | M6811_OP_IMM16 | M6811_OP_BITMASK)))
01017        {
01018          as_bad (_("Immediate operand is not allowed for operand %d."),
01019                 which);
01020          return -1;
01021        }
01022 
01023       mode = M6811_OP_IMM16;
01024       p++;
01025       if (strncmp (p, "%hi", 3) == 0)
01026        {
01027          p += 3;
01028          mode |= M6811_OP_HIGH_ADDR;
01029        }
01030       else if (strncmp (p, "%lo", 3) == 0)
01031        {
01032          p += 3;
01033          mode |= M6811_OP_LOW_ADDR;
01034        }
01035       /* %page modifier is used to obtain only the page number
01036          of the address of a function.  */
01037       else if (strncmp (p, "%page", 5) == 0)
01038        {
01039          p += 5;
01040          mode |= M6811_OP_PAGE_ADDR;
01041        }
01042 
01043       /* %addr modifier is used to obtain the physical address part
01044          of the function (16-bit).  For 68HC12 the function will be
01045          mapped in the 16K window at 0x8000 and the value will be
01046          within that window (although the function address may not fit
01047          in 16-bit).  See bfd/elf32-m68hc12.c for the translation.  */
01048       else if (strncmp (p, "%addr", 5) == 0)
01049        {
01050          p += 5;
01051          mode |= M6811_OP_CALL_ADDR;
01052        }
01053     }
01054   else if (*p == '.' && (p[1] == '+' || p[1] == '-'))
01055     {
01056       p++;
01057       mode = M6811_OP_JUMP_REL;
01058     }
01059   else if (*p == '[')
01060     {
01061       if (current_architecture & cpu6811)
01062        as_bad (_("Indirect indexed addressing is not valid for 68HC11."));
01063 
01064       p++;
01065       mode = M6812_OP_D_IDX;
01066       p = skip_whites (p);
01067     }
01068   else if (*p == ',')              /* Special handling of ,x and ,y.  */
01069     {
01070       p++;
01071       input_line_pointer = p;
01072 
01073       reg = register_name ();
01074       if (reg != REG_NONE)
01075        {
01076          oper->reg1 = reg;
01077          oper->exp.X_op = O_constant;
01078          oper->exp.X_add_number = 0;
01079          oper->mode = M6812_OP_IDX;
01080          return 1;
01081        }
01082       as_bad (_("Spurious `,' or bad indirect register addressing mode."));
01083       return -1;
01084     }
01085   /* Handle 68HC12 page specification in 'call foo,%page(bar)'.  */
01086   else if ((opmode & M6812_OP_PAGE) && strncmp (p, "%page", 5) == 0)
01087     {
01088       p += 5;
01089       mode = M6811_OP_PAGE_ADDR | M6812_OP_PAGE | M6811_OP_IND16;
01090     }
01091   input_line_pointer = p;
01092 
01093   if (mode == M6811_OP_NONE || mode == M6812_OP_D_IDX)
01094     reg = register_name ();
01095   else
01096     reg = REG_NONE;
01097 
01098   if (reg != REG_NONE)
01099     {
01100       p = skip_whites (input_line_pointer);
01101       if (*p == ']' && mode == M6812_OP_D_IDX)
01102        {
01103          as_bad
01104            (_("Missing second register or offset for indexed-indirect mode."));
01105          return -1;
01106        }
01107 
01108       oper->reg1 = reg;
01109       oper->mode = mode | M6812_OP_REG;
01110       if (*p != ',')
01111        {
01112          if (mode == M6812_OP_D_IDX)
01113            {
01114              as_bad (_("Missing second register for indexed-indirect mode."));
01115              return -1;
01116            }
01117          return 1;
01118        }
01119 
01120       p++;
01121       input_line_pointer = p;
01122       reg = register_name ();
01123       if (reg != REG_NONE)
01124        {
01125          p = skip_whites (input_line_pointer);
01126          if (mode == M6812_OP_D_IDX)
01127            {
01128              if (*p != ']')
01129               {
01130                 as_bad (_("Missing `]' to close indexed-indirect mode."));
01131                 return -1;
01132               }
01133              p++;
01134               oper->mode = M6812_OP_D_IDX;
01135            }
01136          input_line_pointer = p;
01137 
01138          oper->reg2 = reg;
01139          return 1;
01140        }
01141       return 1;
01142     }
01143 
01144   /* In MRI mode, isolate the operand because we can't distinguish
01145      operands from comments.  */
01146   if (flag_mri)
01147     {
01148       char c = 0;
01149 
01150       p = skip_whites (p);
01151       while (*p && *p != ' ' && *p != '\t')
01152        p++;
01153 
01154       if (*p)
01155        {
01156          c = *p;
01157          *p = 0;
01158        }
01159 
01160       /* Parse as an expression.  */
01161       expression (&oper->exp);
01162 
01163       if (c)
01164        {
01165          *p = c;
01166        }
01167     }
01168   else
01169     {
01170       expression (&oper->exp);
01171     }
01172 
01173   if (oper->exp.X_op == O_illegal)
01174     {
01175       as_bad (_("Illegal operand."));
01176       return -1;
01177     }
01178   else if (oper->exp.X_op == O_absent)
01179     {
01180       as_bad (_("Missing operand."));
01181       return -1;
01182     }
01183 
01184   p = input_line_pointer;
01185 
01186   if (mode == M6811_OP_NONE || mode == M6811_OP_DIRECT
01187       || mode == M6812_OP_D_IDX)
01188     {
01189       p = skip_whites (input_line_pointer);
01190 
01191       if (*p == ',')
01192        {
01193          int possible_mode = M6811_OP_NONE;
01194          char *old_input_line;
01195 
01196          old_input_line = p;
01197          p++;
01198 
01199          /* 68HC12 pre increment or decrement.  */
01200          if (mode == M6811_OP_NONE)
01201            {
01202              if (*p == '-')
01203               {
01204                 possible_mode = M6812_PRE_DEC;
01205                 p++;
01206               }
01207              else if (*p == '+')
01208               {
01209                 possible_mode = M6812_PRE_INC;
01210                 p++;
01211               }
01212              p = skip_whites (p);
01213            }
01214          input_line_pointer = p;
01215          reg = register_name ();
01216 
01217          /* Backtrack if we have a valid constant expression and
01218             it does not correspond to the offset of the 68HC12 indexed
01219             addressing mode (as in N,x).  */
01220          if (reg == REG_NONE && mode == M6811_OP_NONE
01221              && possible_mode != M6811_OP_NONE)
01222            {
01223              oper->mode = M6811_OP_IND16 | M6811_OP_JUMP_REL;
01224              input_line_pointer = skip_whites (old_input_line);
01225              return 1;
01226            }
01227 
01228          if (possible_mode != M6811_OP_NONE)
01229            mode = possible_mode;
01230 
01231          if ((current_architecture & cpu6811)
01232              && possible_mode != M6811_OP_NONE)
01233            as_bad (_("Pre-increment mode is not valid for 68HC11"));
01234          /* Backtrack.  */
01235          if (which == 0 && opmode & M6812_OP_IDX_P2
01236              && reg != REG_X && reg != REG_Y
01237              && reg != REG_PC && reg != REG_SP)
01238            {
01239              reg = REG_NONE;
01240              input_line_pointer = p;
01241            }
01242 
01243          if (reg == REG_NONE && mode != M6811_OP_DIRECT
01244              && !(mode == M6811_OP_NONE && opmode & M6811_OP_IND16))
01245            {
01246              as_bad (_("Wrong register in register indirect mode."));
01247              return -1;
01248            }
01249          if (mode == M6812_OP_D_IDX)
01250            {
01251              p = skip_whites (input_line_pointer);
01252              if (*p++ != ']')
01253               {
01254                 as_bad (_("Missing `]' to close register indirect operand."));
01255                 return -1;
01256               }
01257              input_line_pointer = p;
01258               oper->reg1 = reg;
01259               oper->mode = M6812_OP_D_IDX_2;
01260               return 1;
01261            }
01262          if (reg != REG_NONE)
01263            {
01264              oper->reg1 = reg;
01265              if (mode == M6811_OP_NONE)
01266               {
01267                 p = input_line_pointer;
01268                 if (*p == '-')
01269                   {
01270                     mode = M6812_POST_DEC;
01271                     p++;
01272                     if (current_architecture & cpu6811)
01273                      as_bad
01274                        (_("Post-decrement mode is not valid for 68HC11."));
01275                   }
01276                 else if (*p == '+')
01277                   {
01278                     mode = M6812_POST_INC;
01279                     p++;
01280                     if (current_architecture & cpu6811)
01281                      as_bad
01282                        (_("Post-increment mode is not valid for 68HC11."));
01283                   }
01284                 else
01285                   mode = M6812_OP_IDX;
01286 
01287                 input_line_pointer = p;
01288               }
01289              else
01290               mode |= M6812_OP_IDX;
01291 
01292              oper->mode = mode;
01293              return 1;
01294            }
01295           input_line_pointer = old_input_line;
01296        }
01297 
01298       if (mode == M6812_OP_D_IDX_2)
01299        {
01300          as_bad (_("Invalid indexed indirect mode."));
01301          return -1;
01302        }
01303     }
01304 
01305   /* If the mode is not known until now, this is either a label
01306      or an indirect address.  */
01307   if (mode == M6811_OP_NONE)
01308     mode = M6811_OP_IND16 | M6811_OP_JUMP_REL;
01309 
01310   p = input_line_pointer;
01311   while (*p == ' ' || *p == '\t')
01312     p++;
01313   input_line_pointer = p;
01314   oper->mode = mode;
01315 
01316   return 1;
01317 }
01318 
01319 #define M6812_AUTO_INC_DEC (M6812_PRE_INC | M6812_PRE_DEC \
01320                             | M6812_POST_INC | M6812_POST_DEC)
01321 
01322 /* Checks that the number 'num' fits for a given mode.  */
01323 static int
01324 check_range (long num, int mode)
01325 {
01326   /* Auto increment and decrement are ok for [-8..8] without 0.  */
01327   if (mode & M6812_AUTO_INC_DEC)
01328     return (num != 0 && num <= 8 && num >= -8);
01329 
01330   /* The 68HC12 supports 5, 9 and 16-bit offsets.  */
01331   if (mode & (M6812_INDEXED_IND | M6812_INDEXED | M6812_OP_IDX))
01332     mode = M6811_OP_IND16;
01333 
01334   if (mode & M6812_OP_JUMP_REL16)
01335     mode = M6811_OP_IND16;
01336 
01337   mode &= ~M6811_OP_BRANCH;
01338   switch (mode)
01339     {
01340     case M6811_OP_IX:
01341     case M6811_OP_IY:
01342     case M6811_OP_DIRECT:
01343       return (num >= 0 && num <= 255) ? 1 : 0;
01344 
01345     case M6811_OP_BITMASK:
01346     case M6811_OP_IMM8:
01347     case M6812_OP_PAGE:
01348       return (((num & 0xFFFFFF00) == 0) || ((num & 0xFFFFFF00) == 0xFFFFFF00))
01349        ? 1 : 0;
01350 
01351     case M6811_OP_JUMP_REL:
01352       return (num >= -128 && num <= 127) ? 1 : 0;
01353 
01354     case M6811_OP_IND16:
01355     case M6811_OP_IND16 | M6812_OP_PAGE:
01356     case M6811_OP_IMM16:
01357       return (((num & 0xFFFF0000) == 0) || ((num & 0xFFFF0000) == 0xFFFF0000))
01358        ? 1 : 0;
01359 
01360     case M6812_OP_IBCC_MARKER:
01361     case M6812_OP_TBCC_MARKER:
01362     case M6812_OP_DBCC_MARKER:
01363       return (num >= -256 && num <= 255) ? 1 : 0;
01364 
01365     case M6812_OP_TRAP_ID:
01366       return ((num >= 0x30 && num <= 0x39)
01367              || (num >= 0x40 && num <= 0x0ff)) ? 1 : 0;
01368 
01369     default:
01370       return 0;
01371     }
01372 }
01373 
01374 /* Gas fixup generation.  */
01375 
01376 /* Put a 1 byte expression described by 'oper'.  If this expression contains
01377    unresolved symbols, generate an 8-bit fixup.  */
01378 static void
01379 fixup8 (expressionS *oper, int mode, int opmode)
01380 {
01381   char *f;
01382 
01383   f = frag_more (1);
01384 
01385   if (oper->X_op == O_constant)
01386     {
01387       if (mode & M6812_OP_TRAP_ID
01388          && !check_range (oper->X_add_number, M6812_OP_TRAP_ID))
01389        {
01390          static char trap_id_warn_once = 0;
01391 
01392          as_bad (_("Trap id `%ld' is out of range."), oper->X_add_number);
01393          if (trap_id_warn_once == 0)
01394            {
01395              trap_id_warn_once = 1;
01396              as_bad (_("Trap id must be within [0x30..0x39] or [0x40..0xff]."));
01397            }
01398        }
01399 
01400       if (!(mode & M6812_OP_TRAP_ID)
01401          && !check_range (oper->X_add_number, mode))
01402        {
01403          as_bad (_("Operand out of 8-bit range: `%ld'."), oper->X_add_number);
01404        }
01405       number_to_chars_bigendian (f, oper->X_add_number & 0x0FF, 1);
01406     }
01407   else if (oper->X_op != O_register)
01408     {
01409       if (mode & M6812_OP_TRAP_ID)
01410        as_bad (_("The trap id must be a constant."));
01411 
01412       if (mode == M6811_OP_JUMP_REL)
01413        {
01414          fixS *fixp;
01415 
01416          fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
01417                            oper, TRUE, BFD_RELOC_8_PCREL);
01418          fixp->fx_pcrel_adjust = 1;
01419        }
01420       else
01421        {
01422          fixS *fixp;
01423           int reloc;
01424 
01425          /* Now create an 8-bit fixup.  If there was some %hi, %lo
01426             or %page modifier, generate the reloc accordingly.  */
01427           if (opmode & M6811_OP_HIGH_ADDR)
01428             reloc = BFD_RELOC_M68HC11_HI8;
01429           else if (opmode & M6811_OP_LOW_ADDR)
01430             reloc = BFD_RELOC_M68HC11_LO8;
01431           else if (opmode & M6811_OP_PAGE_ADDR)
01432             reloc = BFD_RELOC_M68HC11_PAGE;
01433           else
01434             reloc = BFD_RELOC_8;
01435 
01436          fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
01437                               oper, FALSE, reloc);
01438           if (reloc != BFD_RELOC_8)
01439             fixp->fx_no_overflow = 1;
01440        }
01441       number_to_chars_bigendian (f, 0, 1);
01442     }
01443   else
01444     {
01445       as_fatal (_("Operand `%x' not recognized in fixup8."), oper->X_op);
01446     }
01447 }
01448 
01449 /* Put a 2 byte expression described by 'oper'.  If this expression contains
01450    unresolved symbols, generate a 16-bit fixup.  */
01451 static void
01452 fixup16 (expressionS *oper, int mode, int opmode ATTRIBUTE_UNUSED)
01453 {
01454   char *f;
01455 
01456   f = frag_more (2);
01457 
01458   if (oper->X_op == O_constant)
01459     {
01460       if (!check_range (oper->X_add_number, mode))
01461        {
01462          as_bad (_("Operand out of 16-bit range: `%ld'."),
01463                 oper->X_add_number);
01464        }
01465       number_to_chars_bigendian (f, oper->X_add_number & 0x0FFFF, 2);
01466     }
01467   else if (oper->X_op != O_register)
01468     {
01469       fixS *fixp;
01470       int reloc;
01471 
01472       if ((opmode & M6811_OP_CALL_ADDR) && (mode & M6811_OP_IMM16))
01473         reloc = BFD_RELOC_M68HC11_LO16;
01474       else if (mode & M6812_OP_JUMP_REL16)
01475         reloc = BFD_RELOC_16_PCREL;
01476       else if (mode & M6812_OP_PAGE)
01477         reloc = BFD_RELOC_M68HC11_LO16;
01478       else
01479         reloc = BFD_RELOC_16;
01480 
01481       /* Now create a 16-bit fixup.  */
01482       fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 2,
01483                        oper,
01484                        reloc == BFD_RELOC_16_PCREL,
01485                           reloc);
01486       number_to_chars_bigendian (f, 0, 2);
01487       if (reloc == BFD_RELOC_16_PCREL)
01488        fixp->fx_pcrel_adjust = 2;
01489       if (reloc == BFD_RELOC_M68HC11_LO16)
01490         fixp->fx_no_overflow = 1;
01491     }
01492   else
01493     {
01494       as_fatal (_("Operand `%x' not recognized in fixup16."), oper->X_op);
01495     }
01496 }
01497 
01498 /* Put a 3 byte expression described by 'oper'.  If this expression contains
01499    unresolved symbols, generate a 24-bit fixup.  */
01500 static void
01501 fixup24 (expressionS *oper, int mode, int opmode ATTRIBUTE_UNUSED)
01502 {
01503   char *f;
01504 
01505   f = frag_more (3);
01506 
01507   if (oper->X_op == O_constant)
01508     {
01509       if (!check_range (oper->X_add_number, mode))
01510        {
01511          as_bad (_("Operand out of 16-bit range: `%ld'."),
01512                 oper->X_add_number);
01513        }
01514       number_to_chars_bigendian (f, oper->X_add_number & 0x0FFFFFF, 3);
01515     }
01516   else if (oper->X_op != O_register)
01517     {
01518       fixS *fixp;
01519 
01520       /* Now create a 24-bit fixup.  */
01521       fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 3,
01522                        oper, FALSE, BFD_RELOC_M68HC11_24);
01523       number_to_chars_bigendian (f, 0, 3);
01524     }
01525   else
01526     {
01527       as_fatal (_("Operand `%x' not recognized in fixup16."), oper->X_op);
01528     }
01529 }
01530 
01531 /* 68HC11 and 68HC12 code generation.  */
01532 
01533 /* Translate the short branch/bsr instruction into a long branch.  */
01534 static unsigned char
01535 convert_branch (unsigned char code)
01536 {
01537   if (IS_OPCODE (code, M6812_BSR))
01538     return M6812_JSR;
01539   else if (IS_OPCODE (code, M6811_BSR))
01540     return M6811_JSR;
01541   else if (IS_OPCODE (code, M6811_BRA))
01542     return (current_architecture & cpu6812) ? M6812_JMP : M6811_JMP;
01543   else
01544     as_fatal (_("Unexpected branch conversion with `%x'"), code);
01545 
01546   /* Keep gcc happy.  */
01547   return M6811_JSR;
01548 }
01549 
01550 /* Start a new insn that contains at least 'size' bytes.  Record the
01551    line information of that insn in the dwarf2 debug sections.  */
01552 static char *
01553 m68hc11_new_insn (int size)
01554 {
01555   char *f;
01556 
01557   f = frag_more (size);
01558 
01559   dwarf2_emit_insn (size);
01560 
01561   return f;
01562 }
01563 
01564 /* Builds a jump instruction (bra, bcc, bsr).  */
01565 static void
01566 build_jump_insn (struct m68hc11_opcode *opcode, operand operands[],
01567                  int nb_operands, int jmp_mode)
01568 {
01569   unsigned char code;
01570   char *f;
01571   unsigned long n;
01572   fragS *frag;
01573   int where;
01574 
01575   /* The relative branch conversion is not supported for
01576      brclr and brset.  */
01577   assert ((opcode->format & M6811_OP_BITMASK) == 0);
01578   assert (nb_operands == 1);
01579   assert (operands[0].reg1 == REG_NONE && operands[0].reg2 == REG_NONE);
01580 
01581   code = opcode->opcode;
01582 
01583   n = operands[0].exp.X_add_number;
01584 
01585   /* Turn into a long branch:
01586      - when force long branch option (and not for jbcc pseudos),
01587      - when jbcc and the constant is out of -128..127 range,
01588      - when branch optimization is allowed and branch out of range.  */
01589   if ((jmp_mode == 0 && flag_force_long_jumps)
01590       || (operands[0].exp.X_op == O_constant
01591          && (!check_range (n, opcode->format) &&
01592              (jmp_mode == 1 || flag_fixed_branches == 0))))
01593     {
01594       frag = frag_now;
01595       where = frag_now_fix ();
01596 
01597       fix_new (frag_now, frag_now_fix (), 0,
01598                &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
01599 
01600       if (code == M6811_BSR || code == M6811_BRA || code == M6812_BSR)
01601        {
01602          code = convert_branch (code);
01603 
01604          f = m68hc11_new_insn (1);
01605          number_to_chars_bigendian (f, code, 1);
01606        }
01607       else if (current_architecture & cpu6812)
01608        {
01609          /* 68HC12: translate the bcc into a lbcc.  */
01610          f = m68hc11_new_insn (2);
01611          number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1);
01612          number_to_chars_bigendian (f + 1, code, 1);
01613          fixup16 (&operands[0].exp, M6812_OP_JUMP_REL16,
01614                  M6812_OP_JUMP_REL16);
01615          return;
01616        }
01617       else
01618        {
01619          /* 68HC11: translate the bcc into b!cc +3; jmp <L>.  */
01620          f = m68hc11_new_insn (3);
01621          code ^= 1;
01622          number_to_chars_bigendian (f, code, 1);
01623          number_to_chars_bigendian (f + 1, 3, 1);
01624          number_to_chars_bigendian (f + 2, M6811_JMP, 1);
01625        }
01626       fixup16 (&operands[0].exp, M6811_OP_IND16, M6811_OP_IND16);
01627       return;
01628     }
01629 
01630   /* Branch with a constant that must fit in 8-bits.  */
01631   if (operands[0].exp.X_op == O_constant)
01632     {
01633       if (!check_range (n, opcode->format))
01634        {
01635          as_bad (_("Operand out of range for a relative branch: `%ld'"),
01636                   n);
01637        }
01638       else if (opcode->format & M6812_OP_JUMP_REL16)
01639        {
01640          f = m68hc11_new_insn (4);
01641          number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1);
01642          number_to_chars_bigendian (f + 1, code, 1);
01643          number_to_chars_bigendian (f + 2, n & 0x0ffff, 2);
01644        }
01645       else
01646        {
01647          f = m68hc11_new_insn (2);
01648          number_to_chars_bigendian (f, code, 1);
01649          number_to_chars_bigendian (f + 1, n & 0x0FF, 1);
01650        }
01651     }
01652   else if (opcode->format & M6812_OP_JUMP_REL16)
01653     {
01654       frag = frag_now;
01655       where = frag_now_fix ();
01656 
01657       fix_new (frag_now, frag_now_fix (), 0,
01658                &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
01659 
01660       f = m68hc11_new_insn (2);
01661       number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1);
01662       number_to_chars_bigendian (f + 1, code, 1);
01663       fixup16 (&operands[0].exp, M6812_OP_JUMP_REL16, M6812_OP_JUMP_REL16);
01664     }
01665   else
01666     {
01667       char *opcode;
01668 
01669       frag = frag_now;
01670       where = frag_now_fix ();
01671       
01672       fix_new (frag_now, frag_now_fix (), 0,
01673                &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
01674 
01675       /* Branch offset must fit in 8-bits, don't do some relax.  */
01676       if (jmp_mode == 0 && flag_fixed_branches)
01677        {
01678          opcode = m68hc11_new_insn (1);
01679          number_to_chars_bigendian (opcode, code, 1);
01680          fixup8 (&operands[0].exp, M6811_OP_JUMP_REL, M6811_OP_JUMP_REL);
01681        }
01682 
01683       /* bra/bsr made be changed into jmp/jsr.  */
01684       else if (code == M6811_BSR || code == M6811_BRA || code == M6812_BSR)
01685        {
01686           /* Allocate worst case storage.  */
01687          opcode = m68hc11_new_insn (3);
01688          number_to_chars_bigendian (opcode, code, 1);
01689          number_to_chars_bigendian (opcode + 1, 0, 1);
01690          frag_variant (rs_machine_dependent, 1, 1,
01691                         ENCODE_RELAX (STATE_PC_RELATIVE, STATE_UNDF),
01692                         operands[0].exp.X_add_symbol, (offsetT) n,
01693                         opcode);
01694        }
01695       else if (current_architecture & cpu6812)
01696        {
01697          opcode = m68hc11_new_insn (2);
01698          number_to_chars_bigendian (opcode, code, 1);
01699          number_to_chars_bigendian (opcode + 1, 0, 1);
01700          frag_var (rs_machine_dependent, 2, 2,
01701                   ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_UNDF),
01702                   operands[0].exp.X_add_symbol, (offsetT) n, opcode);
01703        }
01704       else
01705        {
01706          opcode = m68hc11_new_insn (2);
01707          number_to_chars_bigendian (opcode, code, 1);
01708          number_to_chars_bigendian (opcode + 1, 0, 1);
01709          frag_var (rs_machine_dependent, 3, 3,
01710                   ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_UNDF),
01711                   operands[0].exp.X_add_symbol, (offsetT) n, opcode);
01712        }
01713     }
01714 }
01715 
01716 /* Builds a dbne/dbeq/tbne/tbeq instruction.  */
01717 static void
01718 build_dbranch_insn (struct m68hc11_opcode *opcode, operand operands[],
01719                     int nb_operands, int jmp_mode)
01720 {
01721   unsigned char code;
01722   char *f;
01723   unsigned long n;
01724 
01725   /* The relative branch conversion is not supported for
01726      brclr and brset.  */
01727   assert ((opcode->format & M6811_OP_BITMASK) == 0);
01728   assert (nb_operands == 2);
01729   assert (operands[0].reg1 != REG_NONE);
01730 
01731   code = opcode->opcode & 0x0FF;
01732 
01733   f = m68hc11_new_insn (1);
01734   number_to_chars_bigendian (f, code, 1);
01735 
01736   n = operands[1].exp.X_add_number;
01737   code = operands[0].reg1;
01738 
01739   if (operands[0].reg1 == REG_NONE || operands[0].reg1 == REG_CCR
01740       || operands[0].reg1 == REG_PC)
01741     as_bad (_("Invalid register for dbcc/tbcc instruction."));
01742 
01743   if (opcode->format & M6812_OP_IBCC_MARKER)
01744     code |= 0x80;
01745   else if (opcode->format & M6812_OP_TBCC_MARKER)
01746     code |= 0x40;
01747 
01748   if (!(opcode->format & M6812_OP_EQ_MARKER))
01749     code |= 0x20;
01750 
01751   /* Turn into a long branch:
01752      - when force long branch option (and not for jbcc pseudos),
01753      - when jdbcc and the constant is out of -256..255 range,
01754      - when branch optimization is allowed and branch out of range.  */
01755   if ((jmp_mode == 0 && flag_force_long_jumps)
01756       || (operands[1].exp.X_op == O_constant
01757          && (!check_range (n, M6812_OP_IBCC_MARKER) &&
01758              (jmp_mode == 1 || flag_fixed_branches == 0))))
01759     {
01760       f = frag_more (2);
01761       code ^= 0x20;
01762       number_to_chars_bigendian (f, code, 1);
01763       number_to_chars_bigendian (f + 1, M6812_JMP, 1);
01764       fixup16 (&operands[0].exp, M6811_OP_IND16, M6811_OP_IND16);
01765       return;
01766     }
01767 
01768   /* Branch with a constant that must fit in 9-bits.  */
01769   if (operands[1].exp.X_op == O_constant)
01770     {
01771       if (!check_range (n, M6812_OP_IBCC_MARKER))
01772        {
01773          as_bad (_("Operand out of range for a relative branch: `%ld'"),
01774                   n);
01775        }
01776       else
01777        {
01778          if ((long) n < 0)
01779            code |= 0x10;
01780 
01781          f = frag_more (2);
01782          number_to_chars_bigendian (f, code, 1);
01783          number_to_chars_bigendian (f + 1, n & 0x0FF, 1);
01784        }
01785     }
01786   else
01787     {
01788       /* Branch offset must fit in 8-bits, don't do some relax.  */
01789       if (jmp_mode == 0 && flag_fixed_branches)
01790        {
01791          fixup8 (&operands[0].exp, M6811_OP_JUMP_REL, M6811_OP_JUMP_REL);
01792        }
01793 
01794       else
01795        {
01796          f = frag_more (2);
01797          number_to_chars_bigendian (f, code, 1);
01798          number_to_chars_bigendian (f + 1, 0, 1);
01799          frag_var (rs_machine_dependent, 3, 3,
01800                   ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_UNDF),
01801                   operands[1].exp.X_add_symbol, (offsetT) n, f);
01802        }
01803     }
01804 }
01805 
01806 #define OP_EXTENDED (M6811_OP_PAGE2 | M6811_OP_PAGE3 | M6811_OP_PAGE4)
01807 
01808 /* Assemble the post index byte for 68HC12 extended addressing modes.  */
01809 static int
01810 build_indexed_byte (operand *op, int format ATTRIBUTE_UNUSED, int move_insn)
01811 {
01812   unsigned char byte = 0;
01813   char *f;
01814   int mode;
01815   long val;
01816 
01817   val = op->exp.X_add_number;
01818   mode = op->mode;
01819   if (mode & M6812_AUTO_INC_DEC)
01820     {
01821       byte = 0x20;
01822       if (mode & (M6812_POST_INC | M6812_POST_DEC))
01823        byte |= 0x10;
01824 
01825       if (op->exp.X_op == O_constant)
01826        {
01827          if (!check_range (val, mode))
01828            {
01829              as_bad (_("Increment/decrement value is out of range: `%ld'."),
01830                     val);
01831            }
01832          if (mode & (M6812_POST_INC | M6812_PRE_INC))
01833            byte |= (val - 1) & 0x07;
01834          else
01835            byte |= (8 - ((val) & 7)) | 0x8;
01836        }
01837       switch (op->reg1)
01838        {
01839        case REG_NONE:
01840          as_fatal (_("Expecting a register."));
01841 
01842        case REG_X:
01843          byte |= 0;
01844          break;
01845 
01846        case REG_Y:
01847          byte |= 0x40;
01848          break;
01849 
01850        case REG_SP:
01851          byte |= 0x80;
01852          break;
01853 
01854        default:
01855          as_bad (_("Invalid register for post/pre increment."));
01856          break;
01857        }
01858 
01859       f = frag_more (1);
01860       number_to_chars_bigendian (f, byte, 1);
01861       return 1;
01862     }
01863 
01864   if (mode & (M6812_OP_IDX | M6812_OP_D_IDX_2))
01865     {
01866       switch (op->reg1)
01867        {
01868        case REG_X:
01869          byte = 0;
01870          break;
01871 
01872        case REG_Y:
01873          byte = 1;
01874          break;
01875 
01876        case REG_SP:
01877          byte = 2;
01878          break;
01879 
01880        case REG_PC:
01881          byte = 3;
01882          break;
01883 
01884        default:
01885          as_bad (_("Invalid register."));
01886          break;
01887        }
01888       if (op->exp.X_op == O_constant)
01889        {
01890          if (!check_range (val, M6812_OP_IDX))
01891            {
01892              as_bad (_("Offset out of 16-bit range: %ld."), val);
01893            }
01894 
01895          if (move_insn && !(val >= -16 && val <= 15))
01896            {
01897              as_bad (_("Offset out of 5-bit range for movw/movb insn: %ld."),
01898                     val);
01899              return -1;
01900            }
01901 
01902          if (val >= -16 && val <= 15 && !(mode & M6812_OP_D_IDX_2))
01903            {
01904              byte = byte << 6;
01905              byte |= val & 0x1f;
01906              f = frag_more (1);
01907              number_to_chars_bigendian (f, byte, 1);
01908              return 1;
01909            }
01910          else if (val >= -256 && val <= 255 && !(mode & M6812_OP_D_IDX_2))
01911            {
01912              byte = byte << 3;
01913              byte |= 0xe0;
01914              if (val < 0)
01915               byte |= 0x1;
01916              f = frag_more (2);
01917              number_to_chars_bigendian (f, byte, 1);
01918              number_to_chars_bigendian (f + 1, val & 0x0FF, 1);
01919              return 2;
01920            }
01921          else
01922            {
01923              byte = byte << 3;
01924              if (mode & M6812_OP_D_IDX_2)
01925               byte |= 0xe3;
01926              else
01927               byte |= 0xe2;
01928 
01929              f = frag_more (3);
01930              number_to_chars_bigendian (f, byte, 1);
01931              number_to_chars_bigendian (f + 1, val & 0x0FFFF, 2);
01932              return 3;
01933            }
01934        }
01935       if (mode & M6812_OP_D_IDX_2)
01936         {
01937           byte = (byte << 3) | 0xe3;
01938           f = frag_more (1);
01939           number_to_chars_bigendian (f, byte, 1);
01940 
01941           fixup16 (&op->exp, 0, 0);
01942         }
01943       else if (op->reg1 != REG_PC)
01944        {
01945           symbolS *sym;
01946           offsetT off;
01947 
01948          f = frag_more (1);
01949          number_to_chars_bigendian (f, byte, 1);
01950           sym = op->exp.X_add_symbol;
01951           off = op->exp.X_add_number;
01952           if (op->exp.X_op != O_symbol)
01953             {
01954               sym = make_expr_symbol (&op->exp);
01955               off = 0;
01956             }
01957          /* movb/movw cannot be relaxed.  */
01958          if (move_insn)
01959            {
01960              byte <<= 6;
01961              number_to_chars_bigendian (f, byte, 1);
01962              fix_new (frag_now, f - frag_now->fr_literal, 1,
01963                      sym, off, 0, BFD_RELOC_M68HC12_5B);
01964              return 1;
01965            }
01966          else
01967            {
01968              number_to_chars_bigendian (f, byte, 1);
01969              frag_var (rs_machine_dependent, 2, 2,
01970                      ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_UNDF),
01971                      sym, off, f);
01972            }
01973        }
01974       else
01975        {
01976          f = frag_more (1);
01977          /* movb/movw cannot be relaxed.  */
01978          if (move_insn)
01979            {
01980              byte <<= 6;
01981              number_to_chars_bigendian (f, byte, 1);
01982              fix_new (frag_now, f - frag_now->fr_literal, 1,
01983                      op->exp.X_add_symbol, op->exp.X_add_number, 0, BFD_RELOC_M68HC12_5B);
01984              return 1;
01985            }
01986          else
01987            {
01988              number_to_chars_bigendian (f, byte, 1);
01989              frag_var (rs_machine_dependent, 2, 2,
01990                      ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_UNDF),
01991                      op->exp.X_add_symbol,
01992                      op->exp.X_add_number, f);
01993            }
01994        }
01995       return 3;
01996     }
01997 
01998   if (mode & (M6812_OP_REG | M6812_OP_D_IDX))
01999     {
02000       if (mode & M6812_OP_D_IDX)
02001        {
02002          if (op->reg1 != REG_D)
02003            as_bad (_("Expecting register D for indexed indirect mode."));
02004          if (move_insn)
02005            as_bad (_("Indexed indirect mode is not allowed for movb/movw."));
02006 
02007          byte = 0xE7;
02008        }
02009       else
02010        {
02011          switch (op->reg1)
02012            {
02013            case REG_A:
02014              byte = 0xE4;
02015              break;
02016 
02017            case REG_B:
02018              byte = 0xE5;
02019              break;
02020 
02021            default:
02022              as_bad (_("Invalid accumulator register."));
02023 
02024            case REG_D:
02025              byte = 0xE6;
02026              break;
02027            }
02028        }
02029       switch (op->reg2)
02030        {
02031        case REG_X:
02032          break;
02033 
02034        case REG_Y:
02035          byte |= (1 << 3);
02036          break;
02037 
02038        case REG_SP:
02039          byte |= (2 << 3);
02040          break;
02041 
02042        case REG_PC:
02043          byte |= (3 << 3);
02044          break;
02045 
02046        default:
02047          as_bad (_("Invalid indexed register."));
02048          break;
02049        }
02050       f = frag_more (1);
02051       number_to_chars_bigendian (f, byte, 1);
02052       return 1;
02053     }
02054 
02055   as_fatal (_("Addressing mode not implemented yet."));
02056   return 0;
02057 }
02058 
02059 /* Assemble the 68HC12 register mode byte.  */
02060 static int
02061 build_reg_mode (operand *op, int format)
02062 {
02063   unsigned char byte;
02064   char *f;
02065 
02066   if (format & M6812_OP_SEX_MARKER
02067       && op->reg1 != REG_A && op->reg1 != REG_B && op->reg1 != REG_CCR)
02068     as_bad (_("Invalid source register for this instruction, use 'tfr'."));
02069   else if (op->reg1 == REG_NONE || op->reg1 == REG_PC)
02070     as_bad (_("Invalid source register."));
02071 
02072   if (format & M6812_OP_SEX_MARKER
02073       && op->reg2 != REG_D
02074       && op->reg2 != REG_X && op->reg2 != REG_Y && op->reg2 != REG_SP)
02075     as_bad (_("Invalid destination register for this instruction, use 'tfr'."));
02076   else if (op->reg2 == REG_NONE || op->reg2 == REG_PC)
02077     as_bad (_("Invalid destination register."));
02078 
02079   byte = (op->reg1 << 4) | (op->reg2);
02080   if (format & M6812_OP_EXG_MARKER)
02081     byte |= 0x80;
02082 
02083   f = frag_more (1);
02084   number_to_chars_bigendian (f, byte, 1);
02085   return 1;
02086 }
02087 
02088 /* build_insn takes a pointer to the opcode entry in the opcode table,
02089    the array of operand expressions and builds the corresponding instruction.
02090    This operation only deals with non relative jumps insn (need special
02091    handling).  */
02092 static void
02093 build_insn (struct m68hc11_opcode *opcode, operand operands[],
02094             int nb_operands ATTRIBUTE_UNUSED)
02095 {
02096   int i;
02097   char *f;
02098   long format;
02099   int move_insn = 0;
02100 
02101   /* Put the page code instruction if there is one.  */
02102   format = opcode->format;
02103 
02104   if (format & M6811_OP_BRANCH)
02105     fix_new (frag_now, frag_now_fix (), 0,
02106              &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
02107 
02108   if (format & OP_EXTENDED)
02109     {
02110       int page_code;
02111 
02112       f = m68hc11_new_insn (2);
02113       if (format & M6811_OP_PAGE2)
02114        page_code = M6811_OPCODE_PAGE2;
02115       else if (format & M6811_OP_PAGE3)
02116        page_code = M6811_OPCODE_PAGE3;
02117       else
02118        page_code = M6811_OPCODE_PAGE4;
02119 
02120       number_to_chars_bigendian (f, page_code, 1);
02121       f++;
02122     }
02123   else
02124     f = m68hc11_new_insn (1);
02125 
02126   number_to_chars_bigendian (f, opcode->opcode, 1);
02127 
02128   i = 0;
02129 
02130   /* The 68HC12 movb and movw instructions are special.  We have to handle
02131      them in a special way.  */
02132   if (format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2))
02133     {
02134       move_insn = 1;
02135       if (format & M6812_OP_IDX)
02136        {
02137          build_indexed_byte (&operands[0], format, 1);
02138          i = 1;
02139          format &= ~M6812_OP_IDX;
02140        }
02141       if (format & M6812_OP_IDX_P2)
02142        {
02143          build_indexed_byte (&operands[1], format, 1);
02144          i = 0;
02145          format &= ~M6812_OP_IDX_P2;
02146        }
02147     }
02148 
02149   if (format & (M6811_OP_DIRECT | M6811_OP_IMM8))
02150     {
02151       fixup8 (&operands[i].exp,
02152              format & (M6811_OP_DIRECT | M6811_OP_IMM8 | M6812_OP_TRAP_ID),
02153              operands[i].mode);
02154       i++;
02155     }
02156   else if (IS_CALL_SYMBOL (format) && nb_operands == 1)
02157     {
02158       format &= ~M6812_OP_PAGE;
02159       fixup24 (&operands[i].exp, format & M6811_OP_IND16,
02160               operands[i].mode);
02161       i++;
02162     }
02163   else if (format & (M6811_OP_IMM16 | M6811_OP_IND16))
02164     {
02165       fixup16 (&operands[i].exp,
02166                format & (M6811_OP_IMM16 | M6811_OP_IND16 | M6812_OP_PAGE),
02167               operands[i].mode);
02168       i++;
02169     }
02170   else if (format & (M6811_OP_IX | M6811_OP_IY))
02171     {
02172       if ((format & M6811_OP_IX) && (operands[0].reg1 != REG_X))
02173        as_bad (_("Invalid indexed register, expecting register X."));
02174       if ((format & M6811_OP_IY) && (operands[0].reg1 != REG_Y))
02175        as_bad (_("Invalid indexed register, expecting register Y."));
02176 
02177       fixup8 (&operands[0].exp, M6811_OP_IX, operands[0].mode);
02178       i = 1;
02179     }
02180   else if (format &
02181           (M6812_OP_IDX | M6812_OP_IDX_2 | M6812_OP_IDX_1
02182             | M6812_OP_D_IDX | M6812_OP_D_IDX_2))
02183     {
02184       build_indexed_byte (&operands[i], format, move_insn);
02185       i++;
02186     }
02187   else if (format & M6812_OP_REG && current_architecture & cpu6812)
02188     {
02189       build_reg_mode (&operands[i], format);
02190       i++;
02191     }
02192   if (format & M6811_OP_BITMASK)
02193     {
02194       fixup8 (&operands[i].exp, M6811_OP_BITMASK, operands[i].mode);
02195       i++;
02196     }
02197   if (format & M6811_OP_JUMP_REL)
02198     {
02199       fixup8 (&operands[i].exp, M6811_OP_JUMP_REL, operands[i].mode);
02200     }
02201   else if (format & M6812_OP_IND16_P2)
02202     {
02203       fixup16 (&operands[1].exp, M6811_OP_IND16, operands[1].mode);
02204     }
02205   if (format & M6812_OP_PAGE)
02206     {
02207       fixup8 (&operands[i].exp, M6812_OP_PAGE, operands[i].mode);
02208     }
02209 }
02210 
02211 /* Opcode identification and operand analysis.  */
02212 
02213 /* find() gets a pointer to an entry in the opcode table.  It must look at all
02214    opcodes with the same name and use the operands to choose the correct
02215    opcode.  Returns the opcode pointer if there was a match and 0 if none.  */
02216 static struct m68hc11_opcode *
02217 find (struct m68hc11_opcode_def *opc, operand operands[], int nb_operands)
02218 {
02219   int i, match, pos;
02220   struct m68hc11_opcode *opcode;
02221   struct m68hc11_opcode *op_indirect;
02222 
02223   op_indirect = 0;
02224   opcode = opc->opcode;
02225 
02226   /* Now search the opcode table table for one with operands
02227      that matches what we've got.  We're only done if the operands matched so
02228      far AND there are no more to check.  */
02229   for (pos = match = 0; match == 0 && pos < opc->nb_modes; pos++, opcode++)
02230     {
02231       int poss_indirect = 0;
02232       long format = opcode->format;
02233       int expect;
02234 
02235       expect = 0;
02236       if (opcode->format & M6811_OP_MASK)
02237        expect++;
02238       if (opcode->format & M6811_OP_BITMASK)
02239        expect++;
02240       if (opcode->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
02241        expect++;
02242       if (opcode->format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2))
02243        expect++;
02244       if ((opcode->format & M6812_OP_PAGE)
02245           && (!IS_CALL_SYMBOL (opcode->format) || nb_operands == 2))
02246         expect++;
02247 
02248       for (i = 0; expect == nb_operands && i < nb_operands; i++)
02249        {
02250          int mode = operands[i].mode;
02251 
02252          if (mode & M6811_OP_IMM16)
02253            {
02254              if (format &
02255                 (M6811_OP_IMM8 | M6811_OP_IMM16 | M6811_OP_BITMASK))
02256               continue;
02257              break;
02258            }
02259          if (mode == M6811_OP_DIRECT)
02260            {
02261              if (format & M6811_OP_DIRECT)
02262               continue;
02263 
02264              /* If the operand is a page 0 operand, remember a
02265                 possible <abs-16> addressing mode.  We mark
02266                 this and continue to check other operands.  */
02267              if (format & M6811_OP_IND16
02268                 && flag_strict_direct_addressing && op_indirect == 0)
02269               {
02270                 poss_indirect = 1;
02271                 continue;
02272               }
02273              break;
02274            }
02275          if (mode & M6811_OP_IND16)
02276            {
02277              if (i == 0 && (format & M6811_OP_IND16) != 0)
02278               continue;
02279               if (i != 0 && (format & M6812_OP_PAGE) != 0)
02280                 continue;
02281              if (i != 0 && (format & M6812_OP_IND16_P2) != 0)
02282               continue;
02283              if (i == 0 && (format & M6811_OP_BITMASK))
02284               break;
02285            }
02286          if (mode & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
02287            {
02288              if (format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
02289               continue;
02290            }
02291          if (mode & M6812_OP_REG)
02292            {
02293              if (i == 0
02294                 && (format & M6812_OP_REG)
02295                 && (operands[i].reg2 == REG_NONE))
02296               continue;
02297              if (i == 0
02298                 && (format & M6812_OP_REG)
02299                 && (format & M6812_OP_REG_2)
02300                 && (operands[i].reg2 != REG_NONE))
02301               continue;
02302              if (i == 0
02303                 && (format & M6812_OP_IDX)
02304                 && (operands[i].reg2 != REG_NONE))
02305               continue;
02306              if (i == 0
02307                 && (format & M6812_OP_IDX)
02308                 && (format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2)))
02309               continue;
02310              if (i == 1
02311                 && (format & M6812_OP_IDX_P2))
02312               continue;
02313              break;
02314            }
02315          if (mode & M6812_OP_IDX)
02316            {
02317              if (format & M6811_OP_IX && operands[i].reg1 == REG_X)
02318               continue;
02319              if (format & M6811_OP_IY && operands[i].reg1 == REG_Y)
02320               continue;
02321              if (i == 0
02322                 && format & (M6812_OP_IDX | M6812_OP_IDX_1 | M6812_OP_IDX_2)
02323                 && (operands[i].reg1 == REG_X
02324                     || operands[i].reg1 == REG_Y
02325                     || operands[i].reg1 == REG_SP
02326                     || operands[i].reg1 == REG_PC))
02327               continue;
02328              if (i == 1 && format & M6812_OP_IDX_P2)
02329               continue;
02330            }
02331           if (mode & format & (M6812_OP_D_IDX | M6812_OP_D_IDX_2))
02332             {
02333               if (i == 0)
02334                 continue;
02335             }
02336          if (mode & M6812_AUTO_INC_DEC)
02337            {
02338              if (i == 0
02339                 && format & (M6812_OP_IDX | M6812_OP_IDX_1 |
02340                             M6812_OP_IDX_2))
02341               continue;
02342              if (i == 1 && format & M6812_OP_IDX_P2)
02343               continue;
02344            }
02345          break;
02346        }
02347       match = i == nb_operands;
02348 
02349       /* Operands are ok but an operand uses page 0 addressing mode
02350          while the insn supports abs-16 mode.  Keep a reference to this
02351          insns in case there is no insn supporting page 0 addressing.  */
02352       if (match && poss_indirect)
02353        {
02354          op_indirect = opcode;
02355          match = 0;
02356        }
02357       if (match)
02358        break;
02359     }
02360 
02361   /* Page 0 addressing is used but not supported by any insn.
02362      If absolute addresses are supported, we use that insn.  */
02363   if (match == 0 && op_indirect)
02364     {
02365       opcode = op_indirect;
02366       match = 1;
02367     }
02368 
02369   if (!match)
02370     {
02371       return (0);
02372     }
02373 
02374   return opcode;
02375 }
02376 
02377 /* Find the real opcode and its associated operands.  We use a progressive
02378    approach here.  On entry, 'opc' points to the first opcode in the
02379    table that matches the opcode name in the source line.  We try to
02380    isolate an operand, find a possible match in the opcode table.
02381    We isolate another operand if no match were found.  The table 'operands'
02382    is filled while operands are recognized.
02383 
02384    Returns the opcode pointer that matches the opcode name in the
02385    source line and the associated operands.  */
02386 static struct m68hc11_opcode *
02387 find_opcode (struct m68hc11_opcode_def *opc, operand operands[],
02388              int *nb_operands)
02389 {
02390   struct m68hc11_opcode *opcode;
02391   int i;
02392 
02393   if (opc->max_operands == 0)
02394     {
02395       *nb_operands = 0;
02396       return opc->opcode;
02397     }
02398 
02399   for (i = 0; i < opc->max_operands;)
02400     {
02401       int result;
02402 
02403       result = get_operand (&operands[i], i, opc->format);
02404       if (result <= 0)
02405        return 0;
02406 
02407       /* Special case where the bitmask of the bclr/brclr
02408          instructions is not introduced by #.
02409          Example: bclr 3,x $80.  */
02410       if (i == 1 && (opc->format & M6811_OP_BITMASK)
02411          && (operands[i].mode & M6811_OP_IND16))
02412        {
02413          operands[i].mode = M6811_OP_IMM16;
02414        }
02415 
02416       i += result;
02417       *nb_operands = i;
02418       if (i >= opc->min_operands)
02419        {
02420          opcode = find (opc, operands, i);
02421 
02422           /* Another special case for 'call foo,page' instructions.
02423              Since we support 'call foo' and 'call foo,page' we must look
02424              if the optional page specification is present otherwise we will
02425              assemble immediately and treat the page spec as garbage.  */
02426           if (opcode && !(opcode->format & M6812_OP_PAGE))
02427              return opcode;
02428 
02429          if (opcode && *input_line_pointer != ',')
02430            return opcode;
02431        }
02432 
02433       if (*input_line_pointer == ',')
02434        input_line_pointer++;
02435     }
02436 
02437   return 0;
02438 }
02439 
02440 #define M6812_XBCC_MARKER (M6812_OP_TBCC_MARKER \
02441                            | M6812_OP_DBCC_MARKER \
02442                            | M6812_OP_IBCC_MARKER)
02443 
02444 /* Gas line assembler entry point.  */
02445 
02446 /* This is the main entry point for the machine-dependent assembler.  str
02447    points to a machine-dependent instruction.  This function is supposed to
02448    emit the frags/bytes it assembles to.  */
02449 void
02450 md_assemble (char *str)
02451 {
02452   struct m68hc11_opcode_def *opc;
02453   struct m68hc11_opcode *opcode;
02454 
02455   unsigned char *op_start, *op_end;
02456   char *save;
02457   char name[20];
02458   int nlen = 0;
02459   operand operands[M6811_MAX_OPERANDS];
02460   int nb_operands = 0;
02461   int branch_optimize = 0;
02462   int alias_id = -1;
02463 
02464   /* Drop leading whitespace.  */
02465   while (*str == ' ')
02466     str++;
02467 
02468   /* Find the opcode end and get the opcode in 'name'.  The opcode is forced
02469      lower case (the opcode table only has lower case op-codes).  */
02470   for (op_start = op_end = (unsigned char *) str;
02471        *op_end && nlen < 20 && !is_end_of_line[*op_end] && *op_end != ' ';
02472        op_end++)
02473     {
02474       name[nlen] = TOLOWER (op_start[nlen]);
02475       nlen++;
02476     }
02477   name[nlen] = 0;
02478 
02479   if (nlen == 0)
02480     {
02481       as_bad (_("No instruction or missing opcode."));
02482       return;
02483     }
02484 
02485   /* Find the opcode definition given its name.  */
02486   opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash, name);
02487 
02488   /* If it's not recognized, look for 'jbsr' and 'jbxx'.  These are
02489      pseudo insns for relative branch.  For these branches, we always
02490      optimize them (turned into absolute branches) even if --short-branches
02491      is given.  */
02492   if (opc == NULL && name[0] == 'j' && name[1] == 'b')
02493     {
02494       opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash, &name[1]);
02495       if (opc
02496          && (!(opc->format & M6811_OP_JUMP_REL)
02497              || (opc->format & M6811_OP_BITMASK)))
02498        opc = 0;
02499       if (opc)
02500        branch_optimize = 1;
02501     }
02502 
02503   /* The following test should probably be removed.  This is not conform
02504      to Motorola assembler specs.  */
02505   if (opc == NULL && flag_mri)
02506     {
02507       if (*op_end == ' ' || *op_end == '\t')
02508        {
02509          while (*op_end == ' ' || *op_end == '\t')
02510            op_end++;
02511 
02512          if (nlen < 19
02513              && (*op_end &&
02514                 (is_end_of_line[op_end[1]]
02515                  || op_end[1] == ' ' || op_end[1] == '\t'
02516                  || !ISALNUM (op_end[1])))
02517              && (*op_end == 'a' || *op_end == 'b'
02518                 || *op_end == 'A' || *op_end == 'B'
02519                 || *op_end == 'd' || *op_end == 'D'
02520                 || *op_end == 'x' || *op_end == 'X'
02521                 || *op_end == 'y' || *op_end == 'Y'))
02522            {
02523              name[nlen++] = TOLOWER (*op_end++);
02524              name[nlen] = 0;
02525              opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash,
02526                                                       name);
02527            }
02528        }
02529     }
02530 
02531   /* Identify a possible instruction alias.  There are some on the
02532      68HC12 to emulate a few 68HC11 instructions.  */
02533   if (opc == NULL && (current_architecture & cpu6812))
02534     {
02535       int i;
02536 
02537       for (i = 0; i < m68hc12_num_alias; i++)
02538        if (strcmp (m68hc12_alias[i].name, name) == 0)
02539          {
02540            alias_id = i;
02541            break;
02542          }
02543     }
02544   if (opc == NULL && alias_id < 0)
02545     {
02546       as_bad (_("Opcode `%s' is not recognized."), name);
02547       return;
02548     }
02549   save = input_line_pointer;
02550   input_line_pointer = (char *) op_end;
02551 
02552   if (opc)
02553     {
02554       opc->used++;
02555       opcode = find_opcode (opc, operands, &nb_operands);
02556     }
02557   else
02558     opcode = 0;
02559 
02560   if ((opcode || alias_id >= 0) && !flag_mri)
02561     {
02562       char *p = input_line_pointer;
02563 
02564       while (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r')
02565        p++;
02566 
02567       if (*p != '\n' && *p)
02568        as_bad (_("Garbage at end of instruction: `%s'."), p);
02569     }
02570 
02571   input_line_pointer = save;
02572 
02573   if (alias_id >= 0)
02574     {
02575       char *f = m68hc11_new_insn (m68hc12_alias[alias_id].size);
02576 
02577       number_to_chars_bigendian (f, m68hc12_alias[alias_id].code1, 1);
02578       if (m68hc12_alias[alias_id].size > 1)
02579        number_to_chars_bigendian (f + 1, m68hc12_alias[alias_id].code2, 1);
02580 
02581       return;
02582     }
02583 
02584   /* Opcode is known but does not have valid operands.  Print out the
02585      syntax for this opcode.  */
02586   if (opcode == 0)
02587     {
02588       if (flag_print_insn_syntax)
02589        print_insn_format (name);
02590 
02591       as_bad (_("Invalid operand for `%s'"), name);
02592       return;
02593     }
02594 
02595   /* Treat dbeq/ibeq/tbeq instructions in a special way.  The branch is
02596      relative and must be in the range -256..255 (9-bits).  */
02597   if ((opcode->format & M6812_XBCC_MARKER)
02598       && (opcode->format & M6811_OP_JUMP_REL))
02599     build_dbranch_insn (opcode, operands, nb_operands, branch_optimize);
02600 
02601   /* Relative jumps instructions are taken care of separately.  We have to make
02602      sure that the relative branch is within the range -128..127.  If it's out
02603      of range, the instructions are changed into absolute instructions.
02604      This is not supported for the brset and brclr instructions.  */
02605   else if ((opcode->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
02606           && !(opcode->format & M6811_OP_BITMASK))
02607     build_jump_insn (opcode, operands, nb_operands, branch_optimize);
02608   else
02609     build_insn (opcode, operands, nb_operands);
02610 }
02611 
02612 
02613 /* Pseudo op to control the ELF flags.  */
02614 static void
02615 s_m68hc11_mode (int x ATTRIBUTE_UNUSED)
02616 {
02617   char *name = input_line_pointer, ch;
02618 
02619   while (!is_end_of_line[(unsigned char) *input_line_pointer])
02620     input_line_pointer++;
02621   ch = *input_line_pointer;
02622   *input_line_pointer = '\0';
02623 
02624   if (strcmp (name, "mshort") == 0)
02625     {
02626       elf_flags &= ~E_M68HC11_I32;
02627     }
02628   else if (strcmp (name, "mlong") == 0)
02629     {
02630       elf_flags |= E_M68HC11_I32;
02631     }
02632   else if (strcmp (name, "mshort-double") == 0)
02633     {
02634       elf_flags &= ~E_M68HC11_F64;
02635     }
02636   else if (strcmp (name, "mlong-double") == 0)
02637     {
02638       elf_flags |= E_M68HC11_F64;
02639     }
02640   else
02641     {
02642       as_warn (_("Invalid mode: %s\n"), name);
02643     }
02644   *input_line_pointer = ch;
02645   demand_empty_rest_of_line ();
02646 }
02647 
02648 /* Mark the symbols with STO_M68HC12_FAR to indicate the functions
02649    are using 'rtc' for returning.  It is necessary to use 'call'
02650    to invoke them.  This is also used by the debugger to correctly
02651    find the stack frame.  */
02652 static void
02653 s_m68hc11_mark_symbol (int mark)
02654 {
02655   char *name;
02656   int c;
02657   symbolS *symbolP;
02658   asymbol *bfdsym;
02659   elf_symbol_type *elfsym;
02660 
02661   do
02662     {
02663       name = input_line_pointer;
02664       c = get_symbol_end ();
02665       symbolP = symbol_find_or_make (name);
02666       *input_line_pointer = c;
02667 
02668       SKIP_WHITESPACE ();
02669 
02670       bfdsym = symbol_get_bfdsym (symbolP);
02671       elfsym = elf_symbol_from (bfd_asymbol_bfd (bfdsym), bfdsym);
02672 
02673       assert (elfsym);
02674 
02675       /* Mark the symbol far (using rtc for function return).  */
02676       elfsym->internal_elf_sym.st_other |= mark;
02677 
02678       if (c == ',')
02679        {
02680          input_line_pointer ++;
02681 
02682          SKIP_WHITESPACE ();
02683 
02684          if (*input_line_pointer == '\n')
02685            c = '\n';
02686        }
02687     }
02688   while (c == ',');
02689 
02690   demand_empty_rest_of_line ();
02691 }
02692 
02693 static void
02694 s_m68hc11_relax (int ignore ATTRIBUTE_UNUSED)
02695 {
02696   expressionS ex;
02697 
02698   expression (&ex);
02699 
02700   if (ex.X_op != O_symbol || ex.X_add_number != 0)
02701     {
02702       as_bad (_("bad .relax format"));
02703       ignore_rest_of_line ();
02704       return;
02705     }
02706 
02707   fix_new_exp (frag_now, frag_now_fix (), 0, &ex, 1,
02708                BFD_RELOC_M68HC11_RL_GROUP);
02709 
02710   demand_empty_rest_of_line ();
02711 }
02712 
02713 
02714 /* Relocation, relaxation and frag conversions.  */
02715 
02716 /* PC-relative offsets are relative to the start of the
02717    next instruction.  That is, the address of the offset, plus its
02718    size, since the offset is always the last part of the insn.  */
02719 long
02720 md_pcrel_from (fixS *fixP)
02721 {
02722   if (fixP->fx_r_type == BFD_RELOC_M68HC11_RL_JUMP)
02723     return 0;
02724 
02725   return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
02726 }
02727 
02728 /* If while processing a fixup, a reloc really needs to be created
02729    then it is done here.  */
02730 arelent *
02731 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
02732 {
02733   arelent *reloc;
02734 
02735   reloc = (arelent *) xmalloc (sizeof (arelent));
02736   reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
02737   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
02738   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
02739   if (fixp->fx_r_type == 0)
02740     reloc->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_16);
02741   else
02742     reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
02743   if (reloc->howto == (reloc_howto_type *) NULL)
02744     {
02745       as_bad_where (fixp->fx_file, fixp->fx_line,
02746                   _("Relocation %d is not supported by object file format."),
02747                   (int) fixp->fx_r_type);
02748       return NULL;
02749     }
02750 
02751   /* Since we use Rel instead of Rela, encode the vtable entry to be
02752      used in the relocation's section offset.  */
02753   if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
02754     reloc->address = fixp->fx_offset;
02755 
02756   reloc->addend = 0;
02757   return reloc;
02758 }
02759 
02760 /* We need a port-specific relaxation function to cope with sym2 - sym1
02761    relative expressions with both symbols in the same segment (but not
02762    necessarily in the same frag as this insn), for example:
02763      ldab sym2-(sym1-2),pc
02764     sym1:
02765    The offset can be 5, 9 or 16 bits long.  */
02766 
02767 long
02768 m68hc11_relax_frag (segT seg ATTRIBUTE_UNUSED, fragS *fragP,
02769                     long stretch ATTRIBUTE_UNUSED)
02770 {
02771   long growth;
02772   offsetT aim = 0;
02773   symbolS *symbolP;
02774   const relax_typeS *this_type;
02775   const relax_typeS *start_type;
02776   relax_substateT next_state;
02777   relax_substateT this_state;
02778   const relax_typeS *table = TC_GENERIC_RELAX_TABLE;
02779 
02780   /* We only have to cope with frags as prepared by
02781      md_estimate_size_before_relax.  The STATE_BITS16 case may geet here
02782      because of the different reasons that it's not relaxable.  */
02783   switch (fragP->fr_subtype)
02784     {
02785     case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS16):
02786     case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16):
02787       /* When we get to this state, the frag won't grow any more.  */
02788       return 0;
02789 
02790     case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS5):
02791     case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS5):
02792     case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS9):
02793     case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9):
02794       if (fragP->fr_symbol == NULL
02795          || S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
02796        as_fatal (_("internal inconsistency problem in %s: fr_symbol %lx"),
02797                 __FUNCTION__, (long) fragP->fr_symbol);
02798       symbolP = fragP->fr_symbol;
02799       if (symbol_resolved_p (symbolP))
02800        as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
02801                 __FUNCTION__);
02802       aim = S_GET_VALUE (symbolP);
02803       break;
02804 
02805     default:
02806       as_fatal (_("internal inconsistency problem in %s: fr_subtype %d"),
02807                 __FUNCTION__, fragP->fr_subtype);
02808     }
02809 
02810   /* The rest is stolen from relax_frag.  There's no obvious way to
02811      share the code, but fortunately no requirement to keep in sync as
02812      long as fragP->fr_symbol does not have its segment changed.  */
02813 
02814   this_state = fragP->fr_subtype;
02815   start_type = this_type = table + this_state;
02816 
02817   if (aim < 0)
02818     {
02819       /* Look backwards.  */
02820       for (next_state = this_type->rlx_more; next_state;)
02821        if (aim >= this_type->rlx_backward)
02822          next_state = 0;
02823        else
02824          {
02825            /* Grow to next state.  */
02826            this_state = next_state;
02827            this_type = table + this_state;
02828            next_state = this_type->rlx_more;
02829          }
02830     }
02831   else
02832     {
02833       /* Look forwards.  */
02834       for (next_state = this_type->rlx_more; next_state;)
02835        if (aim <= this_type->rlx_forward)
02836          next_state = 0;
02837        else
02838          {
02839            /* Grow to next state.  */
02840            this_state = next_state;
02841            this_type = table + this_state;
02842            next_state = this_type->rlx_more;
02843          }
02844     }
02845 
02846   growth = this_type->rlx_length - start_type->rlx_length;
02847   if (growth != 0)
02848     fragP->fr_subtype = this_state;
02849   return growth;
02850 }
02851 
02852 void
02853 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, asection *sec ATTRIBUTE_UNUSED,
02854                  fragS *fragP)
02855 {
02856   fixS *fixp;
02857   long value;
02858   long disp;
02859   char *buffer_address = fragP->fr_literal;
02860 
02861   /* Address in object code of the displacement.  */
02862   register int object_address = fragP->fr_fix + fragP->fr_address;
02863 
02864   buffer_address += fragP->fr_fix;
02865 
02866   /* The displacement of the address, from current location.  */
02867   value = S_GET_VALUE (fragP->fr_symbol);
02868   disp = (value + fragP->fr_offset) - object_address;
02869 
02870   switch (fragP->fr_subtype)
02871     {
02872     case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE):
02873       fragP->fr_opcode[1] = disp;
02874       break;
02875 
02876     case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD):
02877       /* This relax is only for bsr and bra.  */
02878       assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
02879              || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
02880              || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
02881 
02882       fragP->fr_opcode[0] = convert_branch (fragP->fr_opcode[0]);
02883 
02884       fix_new (fragP, fragP->fr_fix - 1, 2,
02885               fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
02886       fragP->fr_fix += 1;
02887       break;
02888 
02889     case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_BYTE):
02890     case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_BYTE):
02891       fragP->fr_opcode[1] = disp;
02892       break;
02893 
02894     case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_WORD):
02895       /* Invert branch.  */
02896       fragP->fr_opcode[0] ^= 1;
02897       fragP->fr_opcode[1] = 3;     /* Branch offset.  */
02898       buffer_address[0] = M6811_JMP;
02899       fix_new (fragP, fragP->fr_fix + 1, 2,
02900               fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
02901       fragP->fr_fix += 3;
02902       break;
02903 
02904     case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_WORD):
02905       /* Translate branch into a long branch.  */
02906       fragP->fr_opcode[1] = fragP->fr_opcode[0];
02907       fragP->fr_opcode[0] = M6811_OPCODE_PAGE2;
02908 
02909       fixp = fix_new (fragP, fragP->fr_fix, 2,
02910                     fragP->fr_symbol, fragP->fr_offset, 1,
02911                     BFD_RELOC_16_PCREL);
02912       fixp->fx_pcrel_adjust = 2;
02913       fragP->fr_fix += 2;
02914       break;
02915 
02916     case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS5):
02917       if (fragP->fr_symbol != 0
02918           && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
02919         value = disp;
02920       /* fall through  */
02921 
02922     case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS5):
02923       fragP->fr_opcode[0] = fragP->fr_opcode[0] << 6;
02924       fragP->fr_opcode[0] |= value & 0x1f;
02925       break;
02926 
02927     case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS9):
02928       /* For a PC-relative offset, use the displacement with a -1 correction
02929          to take into account the additional byte of the insn.  */
02930       if (fragP->fr_symbol != 0
02931           && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
02932         value = disp - 1;
02933       /* fall through  */
02934 
02935     case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9):
02936       fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3);
02937       fragP->fr_opcode[0] |= 0xE0;
02938       fragP->fr_opcode[0] |= (value >> 8) & 1;
02939       fragP->fr_opcode[1] = value;
02940       fragP->fr_fix += 1;
02941       break;
02942 
02943     case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS16):
02944     case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16):
02945       fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3);
02946       fragP->fr_opcode[0] |= 0xe2;
02947       if ((fragP->fr_opcode[0] & 0x0ff) == 0x0fa
02948           && fragP->fr_symbol != 0
02949           && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
02950        {
02951          fixp = fix_new (fragP, fragP->fr_fix, 2,
02952                        fragP->fr_symbol, fragP->fr_offset,
02953                        1, BFD_RELOC_16_PCREL);
02954        }
02955       else
02956        {
02957          fix_new (fragP, fragP->fr_fix, 2,
02958                  fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
02959        }
02960       fragP->fr_fix += 2;
02961       break;
02962 
02963     case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_BYTE):
02964       if (disp < 0)
02965        fragP->fr_opcode[0] |= 0x10;
02966 
02967       fragP->fr_opcode[1] = disp & 0x0FF;
02968       break;
02969 
02970     case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_WORD):
02971       /* Invert branch.  */
02972       fragP->fr_opcode[0] ^= 0x20;
02973       fragP->fr_opcode[1] = 3;     /* Branch offset.  */
02974       buffer_address[0] = M6812_JMP;
02975       fix_new (fragP, fragP->fr_fix + 1, 2,
02976               fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
02977       fragP->fr_fix += 3;
02978       break;
02979 
02980     default:
02981       break;
02982     }
02983 }
02984 
02985 /* On an ELF system, we can't relax a weak symbol.  The weak symbol
02986    can be overridden at final link time by a non weak symbol.  We can
02987    relax externally visible symbol because there is no shared library
02988    and such symbol can't be overridden (unless they are weak).  */
02989 static int
02990 relaxable_symbol (symbolS *symbol)
02991 {
02992   return ! S_IS_WEAK (symbol);
02993 }
02994 
02995 /* Force truly undefined symbols to their maximum size, and generally set up
02996    the frag list to be relaxed.  */
02997 int
02998 md_estimate_size_before_relax (fragS *fragP, asection *segment)
02999 {
03000   if (RELAX_LENGTH (fragP->fr_subtype) == STATE_UNDF)
03001     {
03002       if (S_GET_SEGMENT (fragP->fr_symbol) != segment
03003          || !relaxable_symbol (fragP->fr_symbol)
03004           || (segment != absolute_section
03005               && RELAX_STATE (fragP->fr_subtype) == STATE_INDEXED_OFFSET))
03006        {
03007          /* Non-relaxable cases.  */
03008          int old_fr_fix;
03009          char *buffer_address;
03010 
03011          old_fr_fix = fragP->fr_fix;
03012          buffer_address = fragP->fr_fix + fragP->fr_literal;
03013 
03014          switch (RELAX_STATE (fragP->fr_subtype))
03015            {
03016            case STATE_PC_RELATIVE:
03017 
03018              /* This relax is only for bsr and bra.  */
03019              assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
03020                     || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
03021                     || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
03022 
03023              if (flag_fixed_branches)
03024               as_bad_where (fragP->fr_file, fragP->fr_line,
03025                            _("bra or bsr with undefined symbol."));
03026 
03027              /* The symbol is undefined or in a separate section.
03028                Turn bra into a jmp and bsr into a jsr.  The insn
03029                becomes 3 bytes long (instead of 2).  A fixup is
03030                necessary for the unresolved symbol address.  */
03031              fragP->fr_opcode[0] = convert_branch (fragP->fr_opcode[0]);
03032 
03033              fix_new (fragP, fragP->fr_fix - 1, 2, fragP->fr_symbol,
03034                      fragP->fr_offset, 0, BFD_RELOC_16);
03035              fragP->fr_fix++;
03036              break;
03037 
03038            case STATE_CONDITIONAL_BRANCH:
03039              assert (current_architecture & cpu6811);
03040 
03041              fragP->fr_opcode[0] ^= 1;    /* Reverse sense of branch.  */
03042              fragP->fr_opcode[1] = 3;     /* Skip next jmp insn (3 bytes).  */
03043 
03044              /* Don't use fr_opcode[2] because this may be
03045                in a different frag.  */
03046              buffer_address[0] = M6811_JMP;
03047 
03048              fragP->fr_fix++;
03049              fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
03050                      fragP->fr_offset, 0, BFD_RELOC_16);
03051              fragP->fr_fix += 2;
03052              break;
03053 
03054            case STATE_INDEXED_OFFSET:
03055              assert (current_architecture & cpu6812);
03056 
03057               if (fragP->fr_symbol
03058                   && S_GET_SEGMENT (fragP->fr_symbol) == absolute_section)
03059                 {
03060                    fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_OFFSET,
03061                                                      STATE_BITS5);
03062                    /* Return the size of the variable part of the frag. */
03063                    return md_relax_table[fragP->fr_subtype].rlx_length;
03064                 }
03065               else
03066                 {
03067                    /* Switch the indexed operation to 16-bit mode.  */
03068                    fragP->fr_opcode[0] = fragP->fr_opcode[0] << 3;
03069                    fragP->fr_opcode[0] |= 0xe2;
03070                    fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
03071                             fragP->fr_offset, 0, BFD_RELOC_16);
03072                    fragP->fr_fix += 2;
03073                 }
03074              break;
03075 
03076            case STATE_INDEXED_PCREL:
03077              assert (current_architecture & cpu6812);
03078 
03079               if (fragP->fr_symbol
03080                   && S_GET_SEGMENT (fragP->fr_symbol) == absolute_section)
03081                 {
03082                    fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_PCREL,
03083                                                      STATE_BITS5);
03084                    /* Return the size of the variable part of the frag. */
03085                    return md_relax_table[fragP->fr_subtype].rlx_length;
03086                 }
03087               else
03088                 {
03089                    fixS* fixp;
03090 
03091                    fragP->fr_opcode[0] = fragP->fr_opcode[0] << 3;
03092                    fragP->fr_opcode[0] |= 0xe2;
03093                    fixp = fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
03094                                    fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
03095                    fragP->fr_fix += 2;
03096                 }
03097              break;
03098 
03099            case STATE_XBCC_BRANCH:
03100              assert (current_architecture & cpu6812);
03101 
03102              fragP->fr_opcode[0] ^= 0x20; /* Reverse sense of branch.  */
03103              fragP->fr_opcode[1] = 3;     /* Skip next jmp insn (3 bytes).  */
03104 
03105              /* Don't use fr_opcode[2] because this may be
03106                in a different frag.  */
03107              buffer_address[0] = M6812_JMP;
03108 
03109              fragP->fr_fix++;
03110              fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
03111                      fragP->fr_offset, 0, BFD_RELOC_16);
03112              fragP->fr_fix += 2;
03113              break;
03114 
03115            case STATE_CONDITIONAL_BRANCH_6812:
03116              assert (current_architecture & cpu6812);
03117 
03118              /* Translate into a lbcc branch.  */
03119              fragP->fr_opcode[1] = fragP->fr_opcode[0];
03120              fragP->fr_opcode[0] = M6811_OPCODE_PAGE2;
03121 
03122              fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
03123                        fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
03124              fragP->fr_fix += 2;
03125              break;
03126 
03127            default:
03128              as_fatal (_("Subtype %d is not recognized."), fragP->fr_subtype);
03129            }
03130          frag_wane (fragP);
03131 
03132          /* Return the growth in the fixed part of the frag.  */
03133          return fragP->fr_fix - old_fr_fix;
03134        }
03135 
03136       /* Relaxable cases.  */
03137       switch (RELAX_STATE (fragP->fr_subtype))
03138        {
03139        case STATE_PC_RELATIVE:
03140          /* This relax is only for bsr and bra.  */
03141          assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
03142                 || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
03143                 || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
03144 
03145          fragP->fr_subtype = ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE);
03146          break;
03147 
03148        case STATE_CONDITIONAL_BRANCH:
03149          assert (current_architecture & cpu6811);
03150 
03151          fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH,
03152                                        STATE_BYTE);
03153          break;
03154 
03155        case STATE_INDEXED_OFFSET:
03156          assert (current_architecture & cpu6812);
03157 
03158          fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_OFFSET,
03159                                        STATE_BITS5);
03160          break;
03161 
03162        case STATE_INDEXED_PCREL:
03163          assert (current_architecture & cpu6812);
03164 
03165          fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_PCREL,
03166                                        STATE_BITS5);
03167          break;
03168 
03169        case STATE_XBCC_BRANCH:
03170          assert (current_architecture & cpu6812);
03171 
03172          fragP->fr_subtype = ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_BYTE);
03173          break;
03174 
03175        case STATE_CONDITIONAL_BRANCH_6812:
03176          assert (current_architecture & cpu6812);
03177 
03178          fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812,
03179                                        STATE_BYTE);
03180          break;
03181        }
03182     }
03183 
03184   if (fragP->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))
03185     as_fatal (_("Subtype %d is not recognized."), fragP->fr_subtype);
03186 
03187   /* Return the size of the variable part of the frag.  */
03188   return md_relax_table[fragP->fr_subtype].rlx_length;
03189 }
03190 
03191 /* See whether we need to force a relocation into the output file.  */
03192 int
03193 tc_m68hc11_force_relocation (fixS *fixP)
03194 {
03195   if (fixP->fx_r_type == BFD_RELOC_M68HC11_RL_GROUP)
03196     return 1;
03197 
03198   return generic_force_reloc (fixP);
03199 }
03200 
03201 /* Here we decide which fixups can be adjusted to make them relative
03202    to the beginning of the section instead of the symbol.  Basically
03203    we need to make sure that the linker relaxation is done
03204    correctly, so in some cases we force the original symbol to be
03205    used.  */
03206 int
03207 tc_m68hc11_fix_adjustable (fixS *fixP)
03208 {
03209   switch (fixP->fx_r_type)
03210     {
03211       /* For the linker relaxation to work correctly, these relocs
03212          need to be on the symbol itself.  */
03213     case BFD_RELOC_16:
03214     case BFD_RELOC_M68HC11_RL_JUMP:
03215     case BFD_RELOC_M68HC11_RL_GROUP:
03216     case BFD_RELOC_VTABLE_INHERIT:
03217     case BFD_RELOC_VTABLE_ENTRY:
03218     case BFD_RELOC_32:
03219 
03220       /* The memory bank addressing translation also needs the original
03221          symbol.  */
03222     case BFD_RELOC_M68HC11_LO16:
03223     case BFD_RELOC_M68HC11_PAGE:
03224     case BFD_RELOC_M68HC11_24:
03225       return 0;
03226 
03227     default:
03228       return 1;
03229     }
03230 }
03231 
03232 void
03233 md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
03234 {
03235   char *where;
03236   long value = * valP;
03237   int op_type;
03238 
03239   if (fixP->fx_addsy == (symbolS *) NULL)
03240     fixP->fx_done = 1;
03241 
03242   /* We don't actually support subtracting a symbol.  */
03243   if (fixP->fx_subsy != (symbolS *) NULL)
03244     as_bad_where (fixP->fx_file, fixP->fx_line, _("Expression too complex."));
03245 
03246   op_type = fixP->fx_r_type;
03247 
03248   /* Patch the instruction with the resolved operand.  Elf relocation
03249      info will also be generated to take care of linker/loader fixups.
03250      The 68HC11 addresses only 64Kb, we are only concerned by 8 and 16-bit
03251      relocs.  BFD_RELOC_8 is basically used for .page0 access (the linker
03252      will warn for overflows).  BFD_RELOC_8_PCREL should not be generated
03253      because it's either resolved or turned out into non-relative insns (see
03254      relax table, bcc, bra, bsr transformations)
03255 
03256      The BFD_RELOC_32 is necessary for the support of --gstabs.  */
03257   where = fixP->fx_frag->fr_literal + fixP->fx_where;
03258 
03259   switch (fixP->fx_r_type)
03260     {
03261     case BFD_RELOC_32:
03262       bfd_putb32 ((bfd_vma) value, (unsigned char *) where);
03263       break;
03264 
03265     case BFD_RELOC_24:
03266     case BFD_RELOC_M68HC11_24:
03267       bfd_putb16 ((bfd_vma) (value & 0x0ffff), (unsigned char *) where);
03268       ((bfd_byte*) where)[2] = ((value >> 16) & 0x0ff);
03269       break;
03270 
03271     case BFD_RELOC_16:
03272     case BFD_RELOC_16_PCREL:
03273     case BFD_RELOC_M68HC11_LO16:
03274       bfd_putb16 ((bfd_vma) value, (unsigned char *) where);
03275       if (value < -65537 || value > 65535)
03276        as_bad_where (fixP->fx_file, fixP->fx_line,
03277                     _("Value out of 16-bit range."));
03278       break;
03279 
03280     case BFD_RELOC_M68HC11_HI8:
03281       value = value >> 8;
03282       /* Fall through.  */
03283 
03284     case BFD_RELOC_M68HC11_LO8:
03285     case BFD_RELOC_8:
03286     case BFD_RELOC_M68HC11_PAGE:
03287       ((bfd_byte *) where)[0] = (bfd_byte) value;
03288       break;
03289 
03290     case BFD_RELOC_8_PCREL:
03291       ((bfd_byte *) where)[0] = (bfd_byte) value;
03292 
03293       if (value < -128 || value > 127)
03294        as_bad_where (fixP->fx_file, fixP->fx_line,
03295                     _("Value %ld too large for 8-bit PC-relative branch."),
03296                     value);
03297       break;
03298 
03299     case BFD_RELOC_M68HC11_3B:
03300       if (value <= 0 || value > 8)
03301        as_bad_where (fixP->fx_file, fixP->fx_line,
03302                     _("Auto increment/decrement offset '%ld' is out of range."),
03303                     value);
03304       if (where[0] & 0x8)
03305        value = 8 - value;
03306       else
03307        value--;
03308 
03309       where[0] = where[0] | (value & 0x07);
03310       break;
03311 
03312     case BFD_RELOC_M68HC12_5B:
03313       if (value < -16 || value > 15)
03314        as_bad_where (fixP->fx_file, fixP->fx_line,
03315                     _("Offset out of 5-bit range for movw/movb insn: %ld"),
03316                     value);
03317       if (value >= 0)
03318        where[0] |= value;
03319       else 
03320        where[0] |= (0x10 | (16 + value));
03321       break;
03322 
03323     case BFD_RELOC_M68HC11_RL_JUMP:
03324     case BFD_RELOC_M68HC11_RL_GROUP:
03325     case BFD_RELOC_VTABLE_INHERIT:
03326     case BFD_RELOC_VTABLE_ENTRY:
03327       fixP->fx_done = 0;
03328       return;
03329 
03330     default:
03331       as_fatal (_("Line %d: unknown relocation type: 0x%x."),
03332               fixP->fx_line, fixP->fx_r_type);
03333     }
03334 }
03335 
03336 /* Set the ELF specific flags.  */
03337 void
03338 m68hc11_elf_final_processing (void)
03339 {
03340   if (current_architecture & cpu6812s)
03341     elf_flags |= EF_M68HCS12_MACH;
03342   elf_elfheader (stdoutput)->e_flags &= ~EF_M68HC11_ABI;
03343   elf_elfheader (stdoutput)->e_flags |= elf_flags;
03344 }