Home | History | Annotate | Line # | Download | only in config
      1   1.1  christos /* tc-m68hc11.c -- Assembler code for the Motorola 68HC11 & 68HC12.
      2  1.10  christos    Copyright (C) 1999-2025 Free Software Foundation, Inc.
      3   1.1  christos    Written by Stephane Carrez (stcarrez (at) nerim.fr)
      4   1.1  christos    XGATE and S12X added by James Murray (jsm (at) jsm-net.demon.co.uk)
      5   1.1  christos 
      6   1.1  christos    This file is part of GAS, the GNU Assembler.
      7   1.1  christos 
      8   1.1  christos    GAS is free software; you can redistribute it and/or modify
      9   1.1  christos    it under the terms of the GNU General Public License as published by
     10   1.1  christos    the Free Software Foundation; either version 3, or (at your option)
     11   1.1  christos    any later version.
     12   1.1  christos 
     13   1.1  christos    GAS is distributed in the hope that it will be useful,
     14   1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     15   1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16   1.1  christos    GNU General Public License for more details.
     17   1.1  christos 
     18   1.1  christos    You should have received a copy of the GNU General Public License
     19   1.1  christos    along with GAS; see the file COPYING.  If not, write to
     20   1.1  christos    the Free Software Foundation, 51 Franklin Street - Fifth Floor,
     21   1.1  christos    Boston, MA 02110-1301, USA.  */
     22   1.1  christos 
     23   1.1  christos #include "as.h"
     24   1.1  christos #include "safe-ctype.h"
     25   1.1  christos #include "subsegs.h"
     26   1.1  christos #include "opcode/m68hc11.h"
     27   1.1  christos #include "dwarf2dbg.h"
     28   1.1  christos #include "elf/m68hc11.h"
     29   1.1  christos 
     30   1.1  christos const char comment_chars[] = ";!";
     31   1.1  christos const char line_comment_chars[] = "#*";
     32   1.1  christos const char line_separator_chars[] = "";
     33   1.1  christos 
     34   1.1  christos const char EXP_CHARS[] = "eE";
     35   1.1  christos const char FLT_CHARS[] = "dD";
     36   1.1  christos 
     37   1.1  christos #define STATE_CONDITIONAL_BRANCH	(1)
     38   1.1  christos #define STATE_PC_RELATIVE		(2)
     39   1.1  christos #define STATE_INDEXED_OFFSET            (3)
     40   1.1  christos #define STATE_INDEXED_PCREL             (4)
     41   1.1  christos #define STATE_XBCC_BRANCH               (5)
     42   1.1  christos #define STATE_CONDITIONAL_BRANCH_6812	(6)
     43   1.1  christos 
     44   1.1  christos #define STATE_BYTE			(0)
     45   1.1  christos #define STATE_BITS5                     (0)
     46   1.1  christos #define STATE_WORD			(1)
     47   1.1  christos #define STATE_BITS9                     (1)
     48   1.1  christos #define STATE_LONG			(2)
     49   1.1  christos #define STATE_BITS16                    (2)
     50   1.1  christos #define STATE_UNDF			(3)	/* Symbol undefined in pass1 */
     51   1.1  christos 
     52   1.1  christos /* This macro has no side-effects.  */
     53   1.1  christos #define ENCODE_RELAX(what,length) (((what) << 2) + (length))
     54   1.1  christos #define RELAX_STATE(s) ((s) >> 2)
     55   1.1  christos #define RELAX_LENGTH(s) ((s) & 3)
     56   1.1  christos 
     57   1.1  christos #define IS_OPCODE(C1,C2)        (((C1) & 0x0FF) == ((C2) & 0x0FF))
     58   1.1  christos 
     59   1.1  christos /* This table describes how you change sizes for the various types of variable
     60   1.1  christos    size expressions.  This version only supports two kinds.  */
     61   1.1  christos 
     62   1.1  christos /* The fields are:
     63   1.1  christos    How far Forward this mode will reach.
     64   1.1  christos    How far Backward this mode will reach.
     65   1.1  christos    How many bytes this mode will add to the size of the frag.
     66   1.1  christos    Which mode to go to if the offset won't fit in this one.  */
     67   1.1  christos 
     68   1.1  christos relax_typeS md_relax_table[] =
     69   1.1  christos {
     70   1.1  christos   {1, 1, 0, 0},			/* First entries aren't used.  */
     71   1.1  christos   {1, 1, 0, 0},			/* For no good reason except.  */
     72   1.1  christos   {1, 1, 0, 0},			/* that the VAX doesn't either.  */
     73   1.1  christos   {1, 1, 0, 0},
     74   1.1  christos 
     75   1.1  christos   /* Relax for bcc <L>.
     76   1.1  christos      These insns are translated into b!cc +3 jmp L.  */
     77   1.1  christos   {(127), (-128), 0, ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_WORD)},
     78   1.1  christos   {0, 0, 3, 0},
     79   1.1  christos   {1, 1, 0, 0},
     80   1.1  christos   {1, 1, 0, 0},
     81   1.1  christos 
     82   1.1  christos   /* Relax for bsr <L> and bra <L>.
     83   1.1  christos      These insns are translated into jsr and jmp.  */
     84   1.1  christos   {(127), (-128), 0, ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD)},
     85   1.1  christos   {0, 0, 1, 0},
     86   1.1  christos   {1, 1, 0, 0},
     87   1.1  christos   {1, 1, 0, 0},
     88   1.1  christos 
     89   1.1  christos   /* Relax for indexed offset: 5-bits, 9-bits, 16-bits.  */
     90   1.1  christos   {(15), (-16), 0, ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9)},
     91   1.1  christos   {(255), (-256), 1, ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16)},
     92   1.1  christos   {0, 0, 2, 0},
     93   1.1  christos   {1, 1, 0, 0},
     94   1.1  christos 
     95   1.1  christos   /* Relax for PC relative offset: 5-bits, 9-bits, 16-bits.
     96   1.1  christos      For the 9-bit case, there will be a -1 correction to take into
     97   1.1  christos      account the new byte that's why the range is -255..256.  */
     98   1.1  christos   {(15), (-16), 0, ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS9)},
     99   1.1  christos   {(256), (-255), 1, ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS16)},
    100   1.1  christos   {0, 0, 2, 0},
    101   1.1  christos   {1, 1, 0, 0},
    102   1.1  christos 
    103   1.1  christos   /* Relax for dbeq/ibeq/tbeq r,<L>:
    104   1.1  christos      These insns are translated into db!cc +3 jmp L.  */
    105   1.1  christos   {(255), (-256), 0, ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_WORD)},
    106   1.1  christos   {0, 0, 3, 0},
    107   1.1  christos   {1, 1, 0, 0},
    108   1.1  christos   {1, 1, 0, 0},
    109   1.1  christos 
    110   1.1  christos   /* Relax for bcc <L> on 68HC12.
    111   1.1  christos      These insns are translated into lbcc <L>.  */
    112   1.1  christos   {(127), (-128), 0, ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_WORD)},
    113   1.1  christos   {0, 0, 2, 0},
    114   1.1  christos   {1, 1, 0, 0},
    115   1.1  christos   {1, 1, 0, 0},
    116   1.1  christos 
    117   1.1  christos };
    118   1.1  christos 
    119   1.1  christos /* 68HC11 and 68HC12 registers.  They are numbered according to the 68HC12.  */
    120   1.1  christos typedef enum register_id
    121   1.1  christos {
    122   1.1  christos   REG_NONE = -1,
    123   1.1  christos   REG_A = 0,
    124   1.1  christos   REG_B = 1,
    125   1.1  christos   REG_CCR = 2,
    126   1.1  christos   REG_D = 4,
    127   1.1  christos   REG_X = 5,
    128   1.1  christos   REG_Y = 6,
    129   1.1  christos   REG_SP = 7,
    130   1.1  christos   REG_PC = 8,
    131   1.1  christos   REG_R0 = 0,
    132   1.1  christos   REG_R1 = 1,
    133   1.1  christos   REG_R2 = 2,
    134   1.1  christos   REG_R3 = 3,
    135   1.1  christos   REG_R4 = 4,
    136   1.1  christos   REG_R5 = 5,
    137   1.1  christos   REG_R6 = 6,
    138   1.1  christos   REG_R7 = 7,
    139   1.1  christos   REG_SP_XG = 8,
    140   1.1  christos   REG_PC_XG = 9,
    141   1.1  christos   REG_CCR_XG = 10
    142   1.1  christos } register_id;
    143   1.1  christos 
    144   1.1  christos typedef struct operand
    145   1.1  christos {
    146   1.1  christos   expressionS exp;
    147   1.1  christos   register_id reg1;
    148   1.1  christos   register_id reg2;
    149   1.1  christos   int mode;
    150   1.1  christos } operand;
    151   1.1  christos 
    152   1.1  christos struct m68hc11_opcode_def
    153   1.1  christos {
    154   1.1  christos   long format;
    155   1.1  christos   int min_operands;
    156   1.1  christos   int max_operands;
    157   1.1  christos   int nb_modes;
    158   1.1  christos   int used;
    159   1.1  christos   struct m68hc11_opcode *opcode;
    160   1.1  christos };
    161   1.1  christos 
    162   1.1  christos static struct m68hc11_opcode_def *m68hc11_opcode_defs = 0;
    163   1.1  christos static int m68hc11_nb_opcode_defs = 0;
    164   1.1  christos 
    165   1.1  christos typedef struct alias
    166   1.1  christos {
    167   1.1  christos   const char *name;
    168   1.1  christos   const char *alias;
    169   1.1  christos } alias;
    170   1.1  christos 
    171   1.1  christos static alias alias_opcodes[] =
    172   1.1  christos {
    173   1.1  christos   {"cpd", "cmpd"},
    174   1.1  christos   {"cpx", "cmpx"},
    175   1.1  christos   {"cpy", "cmpy"},
    176   1.1  christos   {0, 0}
    177   1.1  christos };
    178   1.1  christos 
    179   1.1  christos struct m9s12xg_opcode_def
    180   1.1  christos {
    181   1.1  christos   long format;
    182   1.1  christos   int min_operands;
    183   1.1  christos   int max_operands;
    184   1.1  christos   int nb_modes;
    185   1.1  christos   int used;
    186   1.1  christos   struct m9s12xg_opcode *opcode;
    187   1.1  christos };
    188   1.1  christos 
    189   1.1  christos /* Local functions.  */
    190   1.1  christos static register_id reg_name_search (char *);
    191   1.1  christos static register_id register_name (void);
    192   1.1  christos static char *print_opcode_format (struct m68hc11_opcode *, int);
    193   1.1  christos static char *skip_whites (char *);
    194   1.1  christos static int check_range (long, int);
    195   1.1  christos static void print_opcode_list (void);
    196   1.1  christos static void get_default_target (void);
    197   1.1  christos static void print_insn_format (char *);
    198   1.1  christos static int get_operand (operand *, int, long);
    199   1.1  christos static void fixup8 (expressionS *, int, int);
    200   1.1  christos static void fixup16 (expressionS *, int, int);
    201   1.1  christos static void fixup24 (expressionS *, int, int);
    202   1.1  christos static void fixup8_xg (expressionS *, int, int);
    203   1.1  christos static unsigned char convert_branch (unsigned char);
    204   1.1  christos static char *m68hc11_new_insn (int);
    205   1.1  christos static void build_dbranch_insn (struct m68hc11_opcode *,
    206   1.1  christos                                 operand *, int, int);
    207   1.1  christos static int build_indexed_byte (operand *, int, int);
    208   1.1  christos static int build_reg_mode (operand *, int);
    209   1.1  christos 
    210   1.1  christos static struct m68hc11_opcode *find (struct m68hc11_opcode_def *,
    211   1.1  christos                                     operand *, int);
    212   1.1  christos static struct m68hc11_opcode *find_opcode (struct m68hc11_opcode_def *,
    213   1.1  christos                                            operand *, int *);
    214   1.1  christos static void build_jump_insn (struct m68hc11_opcode *, operand *, int, int);
    215   1.1  christos static void build_insn_xg (struct m68hc11_opcode *, operand *, int);
    216   1.1  christos static void build_insn (struct m68hc11_opcode *, operand *, int);
    217   1.1  christos static int relaxable_symbol (symbolS *);
    218   1.1  christos 
    219   1.1  christos /* Pseudo op to indicate a relax group.  */
    220   1.1  christos static void s_m68hc11_relax (int);
    221   1.1  christos 
    222   1.1  christos /* Pseudo op to control the ELF flags.  */
    223   1.1  christos static void s_m68hc11_mode (int);
    224   1.1  christos 
    225   1.1  christos /* Process directives specified via pseudo ops.  */
    226   1.1  christos static void s_m68hc11_parse_pseudo_instruction (int);
    227   1.1  christos 
    228   1.1  christos /* Mark the symbols with STO_M68HC12_FAR to indicate the functions
    229   1.1  christos    are using 'rtc' for returning.  It is necessary to use 'call'
    230   1.1  christos    to invoke them.  This is also used by the debugger to correctly
    231   1.1  christos    find the stack frame.  */
    232   1.1  christos static void s_m68hc11_mark_symbol (int);
    233   1.1  christos 
    234   1.1  christos /* Controls whether relative branches can be turned into long branches.
    235   1.1  christos    When the relative offset is too large, the insn are changed:
    236   1.1  christos     bra -> jmp
    237   1.1  christos     bsr -> jsr
    238   1.1  christos     bcc -> b!cc +3
    239   1.1  christos            jmp L
    240   1.1  christos     dbcc -> db!cc +3
    241   1.1  christos             jmp L
    242   1.1  christos 
    243   1.6  christos   Setting the flag forbids this.  */
    244   1.1  christos static short flag_fixed_branches = 0;
    245   1.1  christos 
    246   1.1  christos /* Force to use long jumps (absolute) instead of relative branches.  */
    247   1.1  christos static short flag_force_long_jumps = 0;
    248   1.1  christos 
    249   1.1  christos /* Change the direct addressing mode into an absolute addressing mode
    250   1.1  christos    when the insn does not support direct addressing.
    251   1.1  christos    For example, "clr *ZD0" is normally not possible and is changed
    252   1.1  christos    into "clr ZDO".  */
    253   1.1  christos static short flag_strict_direct_addressing = 1;
    254   1.1  christos 
    255   1.1  christos /* When an opcode has invalid operand, print out the syntax of the opcode
    256   1.1  christos    to stderr.  */
    257   1.1  christos static short flag_print_insn_syntax = 0;
    258   1.1  christos 
    259   1.1  christos /* Dumps the list of instructions with syntax and then exit:
    260   1.1  christos    1 -> Only dumps the list (sorted by name)
    261   1.1  christos    2 -> Generate an example (or test) that can be compiled.  */
    262   1.1  christos static short flag_print_opcodes = 0;
    263   1.1  christos 
    264   1.1  christos /* Opcode hash table.  */
    265   1.8  christos static htab_t m68hc11_hash;
    266   1.1  christos 
    267   1.1  christos /* Current cpu (either cpu6811 or cpu6812).  This is determined automagically
    268   1.1  christos    by 'get_default_target' by looking at default BFD vector.  This is overridden
    269   1.1  christos    with the -m<cpu> option.  */
    270   1.1  christos static int current_architecture = 0;
    271   1.1  christos 
    272   1.1  christos /* Default cpu determined by 'get_default_target'.  */
    273   1.1  christos static const char *default_cpu;
    274   1.1  christos 
    275   1.1  christos /* Number of opcodes in the sorted table (filtered by current cpu).  */
    276   1.1  christos static int num_opcodes;
    277   1.1  christos 
    278   1.1  christos /* The opcodes sorted by name and filtered by current cpu.  */
    279   1.1  christos static struct m68hc11_opcode *m68hc11_sorted_opcodes;
    280   1.1  christos 
    281   1.1  christos /* ELF flags to set in the output file header.  */
    282   1.1  christos static int elf_flags = E_M68HC11_F64;
    283   1.1  christos 
    284   1.1  christos /* These are the machine dependent pseudo-ops.  These are included so
    285   1.1  christos    the assembler can work on the output from the SUN C compiler, which
    286   1.1  christos    generates these.  */
    287   1.1  christos 
    288   1.1  christos /* This table describes all the machine specific pseudo-ops the assembler
    289   1.1  christos    has to support.  The fields are:
    290   1.1  christos    pseudo-op name without dot
    291   1.1  christos    function to call to execute this pseudo-op
    292   1.1  christos    Integer arg to pass to the function.  */
    293   1.1  christos const pseudo_typeS md_pseudo_table[] =
    294   1.1  christos {
    295   1.1  christos   /* The following pseudo-ops are supported for MRI compatibility.  */
    296   1.1  christos   {"fcb", cons, 1},
    297   1.1  christos   {"fdb", cons, 2},
    298   1.1  christos   {"fqb", cons, 4},
    299   1.1  christos   {"fcc", stringer, 8 + 1},
    300   1.1  christos   {"rmb", s_space, 0},
    301   1.1  christos 
    302   1.1  christos   /* Motorola ALIS.  */
    303   1.1  christos   {"xrefb", s_ignore, 0}, /* Same as xref  */
    304   1.1  christos 
    305   1.1  christos   /* Gcc driven relaxation.  */
    306   1.1  christos   {"relax", s_m68hc11_relax, 0},
    307   1.1  christos 
    308   1.1  christos   /* .mode instruction (ala SH).  */
    309   1.1  christos   {"mode", s_m68hc11_mode, 0},
    310   1.1  christos 
    311   1.1  christos   /* .far instruction.  */
    312   1.1  christos   {"far", s_m68hc11_mark_symbol, STO_M68HC12_FAR},
    313   1.1  christos 
    314   1.1  christos   /* .interrupt instruction.  */
    315   1.1  christos   {"interrupt", s_m68hc11_mark_symbol, STO_M68HC12_INTERRUPT},
    316   1.1  christos 
    317   1.1  christos   /* .nobankwarning instruction.  */
    318   1.1  christos   {"nobankwarning", s_m68hc11_parse_pseudo_instruction, E_M68HC11_NO_BANK_WARNING},
    319   1.1  christos 
    320   1.1  christos   {0, 0, 0}
    321   1.1  christos };
    322   1.1  christos 
    323   1.1  christos /* Options and initialization.  */
    325  1.10  christos 
    326   1.1  christos const char md_shortopts[] = "Sm:";
    327  1.10  christos 
    328   1.1  christos const struct option md_longopts[] =
    329   1.1  christos {
    330   1.1  christos #define OPTION_FORCE_LONG_BRANCH (OPTION_MD_BASE)
    331   1.6  christos   {"force-long-branches", no_argument, NULL, OPTION_FORCE_LONG_BRANCH},
    332   1.1  christos   {"force-long-branchs", no_argument, NULL, OPTION_FORCE_LONG_BRANCH}, /* Misspelled version kept for backwards compatibility.  */
    333   1.1  christos 
    334   1.1  christos #define OPTION_SHORT_BRANCHES     (OPTION_MD_BASE + 1)
    335   1.6  christos   {"short-branches", no_argument, NULL, OPTION_SHORT_BRANCHES},
    336   1.1  christos   {"short-branchs", no_argument, NULL, OPTION_SHORT_BRANCHES}, /* Misspelled version kept for backwards compatibility.  */
    337   1.1  christos 
    338   1.1  christos #define OPTION_STRICT_DIRECT_MODE  (OPTION_MD_BASE + 2)
    339   1.1  christos   {"strict-direct-mode", no_argument, NULL, OPTION_STRICT_DIRECT_MODE},
    340   1.1  christos 
    341   1.1  christos #define OPTION_PRINT_INSN_SYNTAX  (OPTION_MD_BASE + 3)
    342   1.1  christos   {"print-insn-syntax", no_argument, NULL, OPTION_PRINT_INSN_SYNTAX},
    343   1.1  christos 
    344   1.1  christos #define OPTION_PRINT_OPCODES  (OPTION_MD_BASE + 4)
    345   1.1  christos   {"print-opcodes", no_argument, NULL, OPTION_PRINT_OPCODES},
    346   1.1  christos 
    347   1.1  christos #define OPTION_GENERATE_EXAMPLE  (OPTION_MD_BASE + 5)
    348   1.1  christos   {"generate-example", no_argument, NULL, OPTION_GENERATE_EXAMPLE},
    349   1.1  christos 
    350   1.1  christos #define OPTION_MSHORT  (OPTION_MD_BASE + 6)
    351   1.1  christos   {"mshort", no_argument, NULL, OPTION_MSHORT},
    352   1.1  christos 
    353   1.1  christos #define OPTION_MLONG  (OPTION_MD_BASE + 7)
    354   1.1  christos   {"mlong", no_argument, NULL, OPTION_MLONG},
    355   1.1  christos 
    356   1.1  christos #define OPTION_MSHORT_DOUBLE  (OPTION_MD_BASE + 8)
    357   1.1  christos   {"mshort-double", no_argument, NULL, OPTION_MSHORT_DOUBLE},
    358   1.1  christos 
    359   1.1  christos #define OPTION_MLONG_DOUBLE  (OPTION_MD_BASE + 9)
    360   1.1  christos   {"mlong-double", no_argument, NULL, OPTION_MLONG_DOUBLE},
    361   1.1  christos 
    362   1.1  christos #define OPTION_XGATE_RAMOFFSET  (OPTION_MD_BASE + 10)
    363   1.1  christos   {"xgate-ramoffset", no_argument, NULL, OPTION_XGATE_RAMOFFSET},
    364   1.1  christos 
    365   1.1  christos   {NULL, no_argument, NULL, 0}
    366  1.10  christos };
    367   1.1  christos const size_t md_longopts_size = sizeof (md_longopts);
    368   1.1  christos 
    369   1.1  christos /* Get the target cpu for the assembler.  This is based on the configure
    370   1.1  christos    options and on the -m68hc11/-m68hc12 option.  If no option is specified,
    371   1.1  christos    we must get the default.  */
    372   1.1  christos const char *
    373   1.1  christos m68hc11_arch_format (void)
    374   1.1  christos {
    375   1.1  christos   get_default_target ();
    376   1.1  christos   if (current_architecture & cpu6811)
    377   1.1  christos     return "elf32-m68hc11";
    378   1.1  christos   else
    379   1.1  christos     return "elf32-m68hc12";
    380   1.1  christos }
    381   1.1  christos 
    382   1.1  christos enum bfd_architecture
    383   1.1  christos m68hc11_arch (void)
    384   1.1  christos {
    385   1.1  christos   get_default_target ();
    386   1.1  christos   if (current_architecture & cpu6811)
    387   1.1  christos     return bfd_arch_m68hc11;
    388   1.1  christos   else
    389   1.1  christos     return bfd_arch_m68hc12;
    390   1.1  christos }
    391   1.1  christos 
    392   1.1  christos int
    393   1.1  christos m68hc11_mach (void)
    394   1.1  christos {
    395   1.1  christos   return 0;
    396   1.1  christos }
    397   1.1  christos 
    398   1.1  christos /* Listing header selected according to cpu.  */
    399   1.1  christos const char *
    400   1.1  christos m68hc11_listing_header (void)
    401   1.1  christos {
    402   1.1  christos   if (current_architecture & cpu6811)
    403   1.1  christos     return "M68HC11 GAS ";
    404   1.1  christos   else if (current_architecture & cpuxgate)
    405   1.1  christos     return "XGATE GAS ";
    406   1.1  christos   else if (current_architecture & cpu9s12x)
    407   1.1  christos     return "S12X GAS ";
    408   1.1  christos   else
    409   1.1  christos     return "M68HC12 GAS ";
    410   1.1  christos }
    411   1.1  christos 
    412   1.1  christos void
    413   1.1  christos md_show_usage (FILE *stream)
    414   1.1  christos {
    415   1.1  christos   get_default_target ();
    416   1.1  christos   fprintf (stream, _("\
    417   1.1  christos Motorola 68HC11/68HC12/68HCS12 options:\n\
    418   1.1  christos   -m68hc11 | -m68hc12 |\n\
    419   1.1  christos   -m68hcs12 | -mm9s12x |\n\
    420   1.1  christos   -mm9s12xg               specify the processor [default %s]\n\
    421   1.1  christos   -mshort                 use 16-bit int ABI (default)\n\
    422   1.1  christos   -mlong                  use 32-bit int ABI\n\
    423   1.1  christos   -mshort-double          use 32-bit double ABI\n\
    424   1.1  christos   -mlong-double           use 64-bit double ABI (default)\n\
    425   1.1  christos   --force-long-branches   always turn relative branches into absolute ones\n\
    426   1.1  christos   -S,--short-branches     do not turn relative branches into absolute ones\n\
    427   1.1  christos                           when the offset is out of range\n\
    428   1.1  christos   --strict-direct-mode    do not turn the direct mode into extended mode\n\
    429   1.1  christos                           when the instruction does not support direct mode\n\
    430   1.1  christos   --print-insn-syntax     print the syntax of instruction in case of error\n\
    431   1.1  christos   --print-opcodes         print the list of instructions with syntax\n\
    432   1.1  christos   --xgate-ramoffset       offset ram addresses by 0xc000\n\
    433   1.1  christos   --generate-example      generate an example of each instruction\n\
    434   1.1  christos                           (used for testing)\n"), default_cpu);
    435   1.1  christos 
    436   1.1  christos }
    437   1.1  christos 
    438   1.1  christos /* Try to identify the default target based on the BFD library.  */
    439   1.1  christos static void
    440   1.1  christos get_default_target (void)
    441   1.1  christos {
    442   1.1  christos   const bfd_target *target;
    443   1.1  christos   bfd abfd;
    444   1.1  christos 
    445   1.1  christos   if (current_architecture != 0)
    446   1.1  christos     return;
    447   1.1  christos 
    448   1.1  christos   default_cpu = "unknown";
    449   1.1  christos   target = bfd_find_target (0, &abfd);
    450   1.1  christos   if (target && target->name)
    451   1.1  christos     {
    452   1.1  christos       if (strcmp (target->name, "elf32-m68hc12") == 0)
    453   1.1  christos 	{
    454   1.1  christos 	  current_architecture = cpu6812;
    455   1.1  christos 	  default_cpu = "m68hc12";
    456   1.1  christos 	}
    457   1.1  christos       else if (strcmp (target->name, "elf32-m68hc11") == 0)
    458   1.1  christos 	{
    459   1.1  christos 	  current_architecture = cpu6811;
    460   1.1  christos 	  default_cpu = "m68hc11";
    461   1.1  christos 	}
    462   1.1  christos       else
    463   1.1  christos 	{
    464   1.1  christos 	  as_bad (_("Default target `%s' is not supported."), target->name);
    465   1.1  christos 	}
    466   1.1  christos     }
    467   1.1  christos }
    468   1.1  christos 
    469   1.1  christos void
    470   1.1  christos m68hc11_print_statistics (FILE *file)
    471   1.1  christos {
    472   1.1  christos   int i;
    473   1.1  christos   struct m68hc11_opcode_def *opc;
    474   1.8  christos 
    475   1.1  christos   htab_print_statistics (file, "opcode table", m68hc11_hash);
    476   1.1  christos 
    477   1.1  christos   opc = m68hc11_opcode_defs;
    478   1.1  christos   if (opc == 0 || m68hc11_nb_opcode_defs == 0)
    479   1.1  christos     return;
    480   1.1  christos 
    481   1.1  christos   /* Dump the opcode statistics table.  */
    482   1.1  christos   fprintf (file, _("Name   # Modes  Min ops  Max ops  Modes mask  # Used\n"));
    483   1.1  christos   for (i = 0; i < m68hc11_nb_opcode_defs; i++, opc++)
    484   1.1  christos     {
    485   1.1  christos       fprintf (file, "%-7.7s  %5d  %7d  %7d  0x%08lx  %7d\n",
    486   1.1  christos 	       opc->opcode->name,
    487   1.1  christos 	       opc->nb_modes,
    488   1.1  christos 	       opc->min_operands, opc->max_operands, opc->format, opc->used);
    489   1.1  christos     }
    490   1.1  christos }
    491   1.1  christos 
    492   1.5  christos int
    493   1.1  christos md_parse_option (int c, const char *arg)
    494   1.1  christos {
    495   1.1  christos   get_default_target ();
    496   1.1  christos   switch (c)
    497   1.1  christos     {
    498   1.1  christos       /* -S means keep external to 2 bit offset rather than 16 bit one.  */
    499   1.1  christos     case OPTION_SHORT_BRANCHES:
    500   1.1  christos     case 'S':
    501   1.1  christos       flag_fixed_branches = 1;
    502   1.1  christos       break;
    503   1.1  christos 
    504   1.1  christos     case OPTION_FORCE_LONG_BRANCH:
    505   1.1  christos       flag_force_long_jumps = 1;
    506   1.1  christos       break;
    507   1.1  christos 
    508   1.1  christos     case OPTION_PRINT_INSN_SYNTAX:
    509   1.1  christos       flag_print_insn_syntax = 1;
    510   1.1  christos       break;
    511   1.1  christos 
    512   1.1  christos     case OPTION_PRINT_OPCODES:
    513   1.1  christos       flag_print_opcodes = 1;
    514   1.1  christos       break;
    515   1.1  christos 
    516   1.1  christos     case OPTION_STRICT_DIRECT_MODE:
    517   1.1  christos       flag_strict_direct_addressing = 0;
    518   1.1  christos       break;
    519   1.1  christos 
    520   1.1  christos     case OPTION_GENERATE_EXAMPLE:
    521   1.1  christos       flag_print_opcodes = 2;
    522   1.1  christos       break;
    523   1.1  christos 
    524   1.1  christos     case OPTION_MSHORT:
    525   1.1  christos       elf_flags &= ~E_M68HC11_I32;
    526   1.1  christos       break;
    527   1.1  christos 
    528   1.1  christos     case OPTION_MLONG:
    529   1.1  christos       elf_flags |= E_M68HC11_I32;
    530   1.1  christos       break;
    531   1.1  christos 
    532   1.1  christos     case OPTION_MSHORT_DOUBLE:
    533   1.1  christos       elf_flags &= ~E_M68HC11_F64;
    534   1.1  christos       break;
    535   1.1  christos 
    536   1.1  christos     case OPTION_MLONG_DOUBLE:
    537   1.1  christos       elf_flags |= E_M68HC11_F64;
    538   1.1  christos       break;
    539   1.1  christos 
    540   1.1  christos     case OPTION_XGATE_RAMOFFSET:
    541   1.1  christos       elf_flags |= E_M68HC11_XGATE_RAMOFFSET;
    542   1.1  christos       break;
    543   1.1  christos 
    544   1.1  christos     case 'm':
    545   1.1  christos       if ((strcasecmp (arg, "68hc11") == 0)
    546   1.1  christos           || (strcasecmp (arg, "m68hc11") == 0))
    547   1.1  christos 	current_architecture = cpu6811;
    548   1.1  christos       else if ((strcasecmp (arg, "68hc12") == 0)
    549   1.1  christos           || (strcasecmp (arg, "m68hc12") == 0))
    550   1.1  christos 	current_architecture = cpu6812;
    551   1.1  christos       else if ((strcasecmp (arg, "68hcs12") == 0)
    552   1.1  christos           || (strcasecmp (arg, "m68hcs12") == 0))
    553   1.1  christos 	current_architecture = cpu6812 | cpu6812s;
    554   1.1  christos      else if (strcasecmp (arg, "m9s12x") == 0)
    555   1.1  christos 	current_architecture = cpu6812 | cpu6812s | cpu9s12x;
    556   1.1  christos      else if ((strcasecmp (arg, "m9s12xg") == 0)
    557   1.6  christos           || (strcasecmp (arg, "xgate") == 0))
    558   1.1  christos 	/* xgate for backwards compatibility */
    559   1.1  christos 	current_architecture = cpuxgate;
    560   1.1  christos       else
    561   1.1  christos 	as_bad (_("Option `%s' is not recognized."), arg);
    562   1.1  christos       break;
    563   1.1  christos 
    564   1.1  christos     default:
    565   1.1  christos       return 0;
    566   1.1  christos     }
    567   1.1  christos 
    568   1.1  christos   return 1;
    569   1.1  christos }
    570   1.1  christos 
    571   1.1  christos symbolS *
    573   1.1  christos md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
    574   1.1  christos {
    575   1.1  christos   return 0;
    576   1.5  christos }
    577   1.1  christos 
    578   1.1  christos const char *
    579   1.8  christos md_atof (int type, char *litP, int *sizeP)
    580   1.1  christos {
    581   1.1  christos   return ieee_md_atof (type, litP, sizeP, true);
    582   1.1  christos }
    583   1.1  christos 
    584   1.1  christos valueT
    585   1.7  christos md_section_align (asection *seg, valueT addr)
    586  1.10  christos {
    587   1.1  christos   int align = bfd_section_alignment (seg);
    588   1.1  christos   return (addr + ((valueT) 1 << align) - 1) & -((valueT) 1 << align);
    589   1.1  christos }
    590  1.10  christos 
    591   1.1  christos static int
    592  1.10  christos cmp_opcode (const void *p1, const void *p2)
    593  1.10  christos {
    594   1.1  christos   const struct m68hc11_opcode *op1 = p1;
    595   1.1  christos   const struct m68hc11_opcode *op2 = p2;
    596   1.1  christos   return strcmp (op1->name, op2->name);
    597   1.1  christos }
    598   1.1  christos 
    599   1.1  christos #define IS_CALL_SYMBOL(MODE) \
    600   1.1  christos (((MODE) & (M6812_OP_PAGE|M6811_OP_IND16)) \
    601   1.1  christos   == ((M6812_OP_PAGE|M6811_OP_IND16)))
    602   1.1  christos 
    603   1.1  christos /* Initialize the assembler.  Create the opcode hash table
    604   1.1  christos    (sorted on the names) with the M6811 opcode table
    605   1.1  christos    (from opcode library).  */
    606   1.1  christos void
    607   1.5  christos md_begin (void)
    608   1.1  christos {
    609   1.1  christos   const char *prev_name = "";
    610   1.1  christos   struct m68hc11_opcode *opcodes;
    611   1.1  christos   struct m68hc11_opcode_def *opc = 0;
    612   1.1  christos   int i, j;
    613   1.1  christos 
    614   1.8  christos   get_default_target ();
    615   1.1  christos 
    616   1.1  christos   m68hc11_hash = str_htab_create ();
    617   1.5  christos 
    618   1.1  christos   /* Get a writable copy of the opcode table and sort it on the names.  */
    619   1.1  christos   opcodes = XNEWVEC (struct m68hc11_opcode, m68hc11_num_opcodes);
    620   1.1  christos   m68hc11_sorted_opcodes = opcodes;
    621   1.1  christos   num_opcodes = 0;
    622   1.1  christos   for (i = 0; i < m68hc11_num_opcodes; i++)
    623   1.1  christos     {
    624   1.1  christos       if (m68hc11_opcodes[i].arch & current_architecture)
    625   1.1  christos 	{
    626   1.1  christos 	  opcodes[num_opcodes] = m68hc11_opcodes[i];
    627   1.1  christos 	  if (opcodes[num_opcodes].name[0] == 'b'
    628   1.1  christos 	      && opcodes[num_opcodes].format & M6811_OP_JUMP_REL
    629   1.1  christos 	      && !(opcodes[num_opcodes].format & M6811_OP_BITMASK))
    630   1.1  christos 	    {
    631   1.1  christos 	      num_opcodes++;
    632   1.1  christos 	      opcodes[num_opcodes] = m68hc11_opcodes[i];
    633   1.1  christos 	    }
    634   1.1  christos 	  num_opcodes++;
    635   1.1  christos 	  for (j = 0; alias_opcodes[j].name != 0; j++)
    636   1.1  christos 	    if (strcmp (m68hc11_opcodes[i].name, alias_opcodes[j].name) == 0)
    637   1.1  christos 	      {
    638   1.1  christos 		opcodes[num_opcodes] = m68hc11_opcodes[i];
    639   1.1  christos 		opcodes[num_opcodes].name = alias_opcodes[j].alias;
    640   1.1  christos 		num_opcodes++;
    641   1.1  christos 		break;
    642   1.1  christos 	      }
    643  1.10  christos 	}
    644   1.1  christos     }
    645   1.5  christos   qsort (opcodes, num_opcodes, sizeof (struct m68hc11_opcode), cmp_opcode);
    646   1.9  christos 
    647   1.1  christos   opc = XNEWVEC (struct m68hc11_opcode_def, num_opcodes);
    648   1.1  christos   m68hc11_opcode_defs = opc;
    649   1.1  christos 
    650   1.1  christos   /* Insert unique names into hash table.  The M6811 instruction set
    651   1.1  christos      has several identical opcode names that have different opcodes based
    652   1.1  christos      on the operands.  This hash table then provides a quick index to
    653   1.1  christos      the first opcode with a particular name in the opcode table.  */
    654   1.1  christos   for (i = 0; i < num_opcodes; i++, opcodes++)
    655   1.1  christos     {
    656   1.1  christos       int expect;
    657   1.1  christos 
    658   1.9  christos       if (strcmp (prev_name, opcodes->name))
    659   1.1  christos 	{
    660   1.9  christos 	  prev_name = opcodes->name;
    661   1.9  christos 	  opc++;
    662   1.9  christos 	  (opc - 1)->format = 0;
    663   1.9  christos 	  (opc - 1)->min_operands = 100;
    664   1.9  christos 	  (opc - 1)->max_operands = 0;
    665   1.9  christos 	  (opc - 1)->nb_modes = 0;
    666   1.9  christos 	  (opc - 1)->opcode = opcodes;
    667   1.1  christos 	  (opc - 1)->used = 0;
    668   1.9  christos 	  str_hash_insert (m68hc11_hash, opcodes->name, opc - 1, 0);
    669   1.9  christos 	}
    670   1.1  christos       (opc - 1)->nb_modes++;
    671   1.1  christos       (opc - 1)->format |= opcodes->format;
    672   1.1  christos 
    673   1.1  christos       /* See how many operands this opcode needs.  */
    674   1.1  christos       expect = 0;
    675   1.1  christos       if (opcodes->arch == cpuxgate)
    676   1.1  christos 	{
    677   1.1  christos 	  if (opcodes->format & (M68XG_OP_IMM3 | M68XG_OP_R | M68XG_OP_REL9
    678   1.1  christos 				 | M68XG_OP_REL10 ))
    679   1.1  christos 	    expect = 1;
    680   1.1  christos 	  else if (opcodes->format & (M68XG_OP_R_R | M68XG_OP_R_IMM4
    681   1.1  christos 				      | M68XG_OP_R_IMM8 | M68XG_OP_R_IMM8))
    682   1.1  christos 	    expect = 2;
    683   1.1  christos 	  else if (opcodes->format & (M68XG_OP_R_R_R | M68XG_OP_R_R_OFFS5
    684   1.1  christos 				      | M68XG_OP_RD_RB_RI | M68XG_OP_RD_RB_RIp
    685   1.1  christos 				      | M68XG_OP_RD_RB_mRI))
    686   1.1  christos 	    expect = 3;
    687   1.1  christos 	}
    688   1.1  christos       else
    689   1.1  christos 	{
    690   1.1  christos 	  if (opcodes->format & M6811_OP_MASK)
    691   1.1  christos 	    expect++;
    692   1.1  christos 	  if (opcodes->format & M6811_OP_BITMASK)
    693   1.1  christos 	    expect++;
    694   1.1  christos 	  if (opcodes->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
    695   1.1  christos 	    expect++;
    696   1.1  christos 	  if (opcodes->format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2))
    697   1.1  christos 	    expect++;
    698   1.1  christos 	  /* Special case for call instruction.  */
    699   1.1  christos 	  if ((opcodes->format & M6812_OP_PAGE)
    700   1.1  christos 	      && !(opcodes->format & M6811_OP_IND16))
    701   1.1  christos 	    expect++;
    702   1.9  christos 	}
    703   1.9  christos 
    704   1.1  christos       if (expect < (opc - 1)->min_operands)
    705   1.1  christos 	(opc - 1)->min_operands = expect;
    706   1.9  christos       if (IS_CALL_SYMBOL (opcodes->format))
    707   1.9  christos 	expect++;
    708   1.1  christos       if (expect > (opc - 1)->max_operands)
    709   1.1  christos 	(opc - 1)->max_operands = expect;
    710   1.1  christos     }
    711   1.1  christos   m68hc11_nb_opcode_defs = opc - m68hc11_opcode_defs;
    712   1.1  christos 
    713   1.1  christos   if (flag_print_opcodes)
    714   1.1  christos     {
    715   1.1  christos       print_opcode_list ();
    716   1.1  christos       exit (EXIT_SUCCESS);
    717   1.1  christos     }
    718   1.1  christos }
    719   1.1  christos 
    720   1.1  christos void
    721   1.1  christos m68hc11_init_after_args (void)
    722   1.1  christos {
    723   1.1  christos }
    724   1.1  christos 
    725   1.1  christos /* Builtin help.  */
    727   1.1  christos 
    728   1.1  christos /* Return a string that represents the operand format for the instruction.
    729   1.1  christos    When example is true, this generates an example of operand.  This is used
    730   1.1  christos    to give an example and also to generate a test.  */
    731   1.1  christos 
    732   1.1  christos static char *
    733   1.1  christos print_opcode_format (struct m68hc11_opcode *opcode, int example)
    734   1.1  christos {
    735   1.1  christos   static char buf[128];
    736   1.1  christos   int format = opcode->format;
    737   1.1  christos   char *p;
    738   1.1  christos 
    739   1.1  christos   p = buf;
    740   1.1  christos   buf[0] = 0;
    741   1.1  christos 
    742   1.1  christos   if (current_architecture == cpuxgate)
    743   1.1  christos     {
    744   1.1  christos       if (format & M68XG_OP_IMM3)
    745   1.1  christos 	{
    746   1.1  christos 	  if (example)
    747   1.1  christos 	    sprintf (p, "#%d", rand () & 0x007);
    748   1.1  christos 	  else
    749   1.1  christos 	    strcpy (p, _("imm3"));
    750   1.1  christos 	  p = &p[strlen (p)];
    751   1.1  christos 	}
    752   1.1  christos       else if (format & M68XG_OP_R)
    753   1.1  christos 	{
    754   1.1  christos 	  if (example)
    755   1.1  christos 	    sprintf (p, "R%d", rand () & 0x07);
    756   1.1  christos 	  else
    757   1.1  christos 	    strcpy (p, _("RD"));
    758   1.1  christos 	  p = &p[strlen (p)];
    759   1.1  christos 	}
    760   1.1  christos       else if (format & M68XG_OP_R_R)
    761   1.1  christos 	{
    762   1.1  christos 	  if (example)
    763   1.1  christos 	    sprintf (p, "R%d,R%d", rand () & 0x07, rand () & 0x07);
    764   1.1  christos 	  else
    765   1.1  christos 	    strcpy (p, _("RD,RS"));
    766   1.1  christos 	  p = &p[strlen (p)];
    767   1.1  christos 	}
    768   1.1  christos       else if (format & M68XG_OP_R_IMM4)
    769   1.1  christos 	{
    770   1.1  christos 	  if (example)
    771   1.1  christos 	    sprintf (p, "R%d,#%d", rand () & 0x07, rand () & 0x0f);
    772   1.1  christos 	  else
    773   1.1  christos     	    strcpy (p, _("RI, #imm4"));
    774   1.1  christos 	  p = &p[strlen (p)];
    775   1.1  christos 	}
    776   1.1  christos       else if (format & M68XG_OP_R_R_R)
    777   1.1  christos 	{
    778   1.1  christos 	  if (example)
    779   1.1  christos 	    sprintf (p, "R%d,R%d,R%d", rand () & 0x07, rand () & 0x07, rand () & 0x07);
    780   1.1  christos 	  else
    781   1.1  christos 	    strcpy (p, "RD,RS1,RS2");
    782   1.1  christos 	  p = &p[strlen (p)];
    783   1.1  christos 	}
    784   1.1  christos       else if (format & M68XG_OP_REL9)
    785   1.1  christos 	{
    786   1.1  christos 	  if (example)
    787   1.1  christos 	    sprintf (p, "%d", rand () & 0x1FF);
    788   1.1  christos 	  else
    789   1.1  christos 	    strcpy (p, "<rel9>");
    790   1.1  christos 	  p = &p[strlen (p)];
    791   1.1  christos 	}
    792   1.1  christos       else if (format & M68XG_OP_REL10)
    793   1.1  christos 	{
    794   1.1  christos 	  if (example)
    795   1.1  christos 	    sprintf (p, "%d", rand () & 0x3FF);
    796   1.1  christos 	  else
    797   1.1  christos     	    strcpy (p, "<rel10>");
    798   1.1  christos 	  p = &p[strlen (p)];
    799   1.1  christos 	}
    800   1.1  christos       else if (format & M68XG_OP_R_R_OFFS5)
    801   1.1  christos 	{
    802   1.1  christos 	  if (example)
    803   1.1  christos 	    sprintf (p, "R%d, (R%d, #0x%x)", rand () & 0x07, rand () & 0x07, rand () & 0x1f);
    804   1.1  christos 	  else
    805   1.1  christos 	    strcpy (p, _("RD, (RI,#offs5)"));
    806   1.1  christos 	  p = &p[strlen (p)];
    807   1.1  christos 	}
    808   1.1  christos       else if (format & M68XG_OP_RD_RB_RI)
    809   1.1  christos 	{
    810   1.1  christos 	  if (example)
    811   1.1  christos 	    sprintf (p, "R%d, (R%d, R%d)", rand () & 0x07, rand () & 0x07, rand () & 0x07);
    812   1.1  christos 	  else
    813   1.1  christos 	    strcpy (p, "RD, (RB, RI)");
    814   1.1  christos 	  p = &p[strlen (p)];
    815   1.1  christos 	}
    816   1.1  christos       else if (format & M68XG_OP_RD_RB_RIp)
    817   1.1  christos 	{
    818   1.1  christos 	  if (example)
    819   1.1  christos 	    sprintf (p, "R%d, (R%d, R%d+)", rand () & 0x07, rand () & 0x07, rand () & 0x07);
    820   1.1  christos 	  else
    821   1.1  christos 	    strcpy (p, "RD, (RB, RI+)");
    822   1.1  christos 	  p = &p[strlen (p)];
    823   1.1  christos 	}
    824   1.1  christos       else if (format & M68XG_OP_RD_RB_mRI)
    825   1.1  christos 	{
    826   1.1  christos 	  if (example)
    827   1.1  christos 	    sprintf (p, "R%d, (R%d, -R%d)", rand () & 0x07, rand () & 0x07, rand () & 0x07);
    828   1.1  christos 	  else
    829   1.1  christos 	    strcpy (p, "RD, (RB, -RI)");
    830   1.1  christos 	  p = &p[strlen (p)];
    831   1.1  christos 	}
    832   1.1  christos       else if (format & M68XG_OP_R_IMM8)
    833   1.1  christos 	{
    834   1.1  christos 	  if (example)
    835   1.1  christos 	    sprintf (p, "R%d, #0x%x", rand () & 0x07, rand () & 0xff);
    836   1.1  christos 	  else
    837   1.1  christos 	    strcpy (p, "RD, #imm8");
    838   1.1  christos 	  p = &p[strlen (p)];
    839   1.1  christos 	}
    840   1.1  christos       else if (format & M68XG_OP_R_IMM16)
    841   1.1  christos 	{
    842   1.1  christos 	  if (example)
    843   1.1  christos 	    sprintf (p, "R%d, #0x%x", rand () & 0x07, rand () & 0xffff);
    844   1.1  christos 	  else
    845   1.1  christos 	    strcpy (p, "RD, #imm16");
    846   1.1  christos 	  p = &p[strlen (p)];
    847   1.1  christos 	}
    848   1.1  christos     }
    849   1.1  christos   else
    850   1.1  christos     {
    851   1.1  christos 
    852   1.1  christos       if (format & M6811_OP_IMM8)
    853   1.1  christos 	{
    854   1.1  christos 	  if (example)
    855   1.1  christos 	    sprintf (p, "#%d", rand () & 0x0FF);
    856   1.1  christos 	  else
    857   1.1  christos 	    strcpy (p, _("#<imm8>"));
    858   1.1  christos 	  p = &p[strlen (p)];
    859   1.1  christos 	}
    860   1.1  christos 
    861   1.1  christos       if (format & M6811_OP_IMM16)
    862   1.1  christos 	{
    863   1.1  christos 	  if (example)
    864   1.1  christos 	    sprintf (p, "#%d", rand () & 0x0FFFF);
    865   1.1  christos 	  else
    866   1.1  christos 	    strcpy (p, _("#<imm16>"));
    867   1.1  christos 	  p = &p[strlen (p)];
    868   1.1  christos 	}
    869   1.1  christos 
    870   1.1  christos       if (format & M6811_OP_IX)
    871   1.1  christos 	{
    872   1.1  christos 	  if (example)
    873   1.1  christos 	    sprintf (p, "%d,X", rand () & 0x0FF);
    874   1.1  christos 	  else
    875   1.1  christos 	    strcpy (p, _("<imm8>,X"));
    876   1.1  christos 	  p = &p[strlen (p)];
    877   1.1  christos 	}
    878   1.1  christos 
    879   1.1  christos       if (format & M6811_OP_IY)
    880   1.1  christos 	{
    881   1.1  christos 	  if (example)
    882   1.1  christos 	    sprintf (p, "%d,X", rand () & 0x0FF);
    883   1.1  christos 	  else
    884   1.1  christos 	    strcpy (p, _("<imm8>,X"));
    885   1.1  christos 	  p = &p[strlen (p)];
    886   1.1  christos 	}
    887   1.1  christos 
    888   1.1  christos       if (format & M6812_OP_IDX)
    889   1.1  christos 	{
    890   1.1  christos 	  if (example)
    891   1.1  christos 	    sprintf (p, "%d,X", rand () & 0x0FF);
    892   1.1  christos 	  else
    893   1.1  christos 	    strcpy (p, "n,r");
    894   1.1  christos 	  p = &p[strlen (p)];
    895   1.1  christos 	}
    896   1.1  christos 
    897   1.1  christos       if (format & M6812_OP_PAGE)
    898   1.1  christos 	{
    899   1.1  christos 	  if (example)
    900   1.1  christos 	    sprintf (p, ", %d", rand () & 0x0FF);
    901   1.1  christos 	  else
    902   1.1  christos 	    strcpy (p, ", <page>");
    903   1.1  christos 	  p = &p[strlen (p)];
    904   1.1  christos 	}
    905   1.1  christos 
    906   1.1  christos       if (format & M6811_OP_DIRECT)
    907   1.1  christos 	{
    908   1.1  christos 	  if (example)
    909   1.1  christos 	    sprintf (p, "*Z%d", rand () & 0x0FF);
    910   1.1  christos 	  else
    911   1.1  christos 	    strcpy (p, _("*<abs8>"));
    912   1.1  christos 	  p = &p[strlen (p)];
    913   1.1  christos 	}
    914   1.1  christos 
    915   1.1  christos       if (format & M6811_OP_BITMASK)
    916   1.1  christos 	{
    917   1.1  christos 	  if (buf[0])
    918   1.1  christos 	    *p++ = ' ';
    919   1.1  christos 
    920   1.1  christos 	  if (example)
    921   1.1  christos 	    sprintf (p, "#$%02x", rand () & 0x0FF);
    922   1.1  christos 	  else
    923   1.1  christos 	    strcpy (p, _("#<mask>"));
    924   1.1  christos 
    925   1.1  christos 	  p = &p[strlen (p)];
    926   1.1  christos 	  if (format & M6811_OP_JUMP_REL)
    927   1.1  christos 	    *p++ = ' ';
    928   1.1  christos 	}
    929   1.1  christos 
    930   1.1  christos       if (format & M6811_OP_IND16)
    931   1.1  christos 	{
    932   1.1  christos 	  if (example)
    933   1.1  christos 	    sprintf (p, _("symbol%d"), rand () & 0x0FF);
    934   1.1  christos 	  else
    935   1.1  christos 	    strcpy (p, _("<abs>"));
    936   1.1  christos 
    937   1.1  christos 	  p = &p[strlen (p)];
    938   1.1  christos 	}
    939   1.1  christos 
    940   1.1  christos       if (format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
    941   1.1  christos 	{
    942   1.1  christos 	  if (example)
    943   1.1  christos 	    {
    944   1.1  christos 	      if (format & M6811_OP_BITMASK)
    945   1.1  christos 		{
    946   1.1  christos 		  sprintf (p, ".+%d", rand () & 0x7F);
    947   1.1  christos 		}
    948   1.1  christos 	      else
    949   1.1  christos 		{
    950   1.1  christos 		  sprintf (p, "L%d", rand () & 0x0FF);
    951   1.1  christos 		}
    952   1.1  christos 	    }
    953   1.1  christos 	  else
    954   1.1  christos 	    strcpy (p, _("<label>"));
    955   1.1  christos 	}
    956   1.1  christos     }
    957   1.1  christos   return buf;
    958   1.1  christos }
    959   1.1  christos 
    960   1.1  christos /* Prints the list of instructions with the possible operands.  */
    961   1.1  christos static void
    962   1.5  christos print_opcode_list (void)
    963   1.1  christos {
    964   1.1  christos   int i;
    965   1.1  christos   const char *prev_name = "";
    966   1.1  christos   struct m68hc11_opcode *opcodes;
    967   1.1  christos   int example = flag_print_opcodes == 2;
    968   1.1  christos 
    969   1.1  christos   if (example)
    970   1.1  christos     printf (_("# Example of `%s' instructions\n\t.sect .text\n_start:\n"),
    971   1.1  christos 	    default_cpu);
    972   1.1  christos 
    973   1.1  christos   opcodes = m68hc11_sorted_opcodes;
    974   1.1  christos 
    975   1.1  christos   /* Walk the list sorted on names (by md_begin).  We only report
    976   1.1  christos      one instruction per line, and we collect the different operand
    977   1.1  christos      formats.  */
    978   1.1  christos   for (i = 0; i < num_opcodes; i++, opcodes++)
    979   1.1  christos     {
    980   1.1  christos       char *fmt = print_opcode_format (opcodes, example);
    981   1.1  christos 
    982   1.1  christos       if (example)
    983   1.1  christos 	{
    984   1.1  christos 	  printf ("L%d:\t", i);
    985   1.1  christos 	  printf ("%s %s\n", opcodes->name, fmt);
    986   1.1  christos 	}
    987   1.1  christos       else
    988   1.1  christos 	{
    989   1.1  christos 	  if (strcmp (prev_name, opcodes->name))
    990   1.1  christos 	    {
    991   1.1  christos 	      if (i > 0)
    992  1.10  christos 		printf ("\n");
    993   1.1  christos 
    994   1.1  christos 	      printf ("%-5.5s ", opcodes->name);
    995   1.1  christos 	      prev_name = opcodes->name;
    996   1.1  christos 	    }
    997   1.1  christos 	  if (fmt[0])
    998   1.1  christos 	    printf ("  [%s]", fmt);
    999   1.1  christos 	}
   1000   1.1  christos     }
   1001   1.1  christos   printf ("\n");
   1002   1.1  christos }
   1003   1.1  christos 
   1004   1.1  christos /* Print the instruction format.  This operation is called when some
   1005   1.1  christos    instruction is not correct.  Instruction format is printed as an
   1006   1.1  christos    error message.  */
   1007   1.1  christos static void
   1008   1.1  christos print_insn_format (char *name)
   1009   1.1  christos {
   1010   1.1  christos   struct m68hc11_opcode_def *opc;
   1011  1.10  christos   struct m68hc11_opcode *opcode;
   1012   1.1  christos   char buf[128];
   1013   1.1  christos 
   1014   1.1  christos   opc = str_hash_find (m68hc11_hash, name);
   1015   1.1  christos   if (opc == NULL)
   1016   1.1  christos     {
   1017   1.1  christos       as_bad (_("Instruction `%s' is not recognized."), name);
   1018   1.1  christos       return;
   1019   1.1  christos     }
   1020   1.1  christos   opcode = opc->opcode;
   1021   1.1  christos 
   1022   1.1  christos   as_bad (_("Instruction formats for `%s':"), name);
   1023   1.1  christos   do
   1024   1.1  christos     {
   1025   1.1  christos       char *fmt;
   1026   1.1  christos 
   1027   1.1  christos       fmt = print_opcode_format (opcode, 0);
   1028   1.1  christos       sprintf (buf, "\t%-5.5s %s", opcode->name, fmt);
   1029   1.1  christos 
   1030   1.1  christos       as_bad ("%s", buf);
   1031   1.1  christos       opcode++;
   1032   1.1  christos     }
   1033   1.1  christos   while (strcmp (opcode->name, name) == 0);
   1034   1.1  christos }
   1035   1.1  christos 
   1036   1.1  christos /* Analysis of 68HC11 and 68HC12 operands.  */
   1038   1.1  christos 
   1039   1.1  christos /* reg_name_search() finds the register number given its name.
   1040   1.1  christos    Returns the register number or REG_NONE on failure.  */
   1041   1.1  christos static register_id
   1042   1.1  christos reg_name_search (char *name)
   1043   1.1  christos {
   1044   1.1  christos   if (strcasecmp (name, "x") == 0 || strcasecmp (name, "ix") == 0)
   1045   1.1  christos     return REG_X;
   1046   1.1  christos   if (strcasecmp (name, "y") == 0 || strcasecmp (name, "iy") == 0)
   1047   1.1  christos     return REG_Y;
   1048   1.1  christos   if (strcasecmp (name, "a") == 0)
   1049   1.1  christos     return REG_A;
   1050   1.1  christos   if (strcasecmp (name, "b") == 0)
   1051   1.1  christos     return REG_B;
   1052   1.1  christos   if (strcasecmp (name, "d") == 0)
   1053   1.1  christos     return REG_D;
   1054   1.1  christos   if (strcasecmp (name, "sp") == 0)
   1055   1.1  christos     return REG_SP;
   1056   1.1  christos   if (strcasecmp (name, "pc") == 0)
   1057   1.1  christos     return REG_PC;
   1058   1.1  christos   if (strcasecmp (name, "ccr") == 0)
   1059   1.1  christos     return REG_CCR;
   1060   1.1  christos /* XGATE */
   1061   1.1  christos   if (strcasecmp (name, "r0") == 0)
   1062   1.1  christos     return REG_R0;
   1063   1.1  christos   if (strcasecmp (name, "r1") == 0)
   1064   1.1  christos     return REG_R1;
   1065   1.1  christos   if (strcasecmp (name, "r2") == 0)
   1066   1.1  christos     return REG_R2;
   1067   1.1  christos   if (strcasecmp (name, "r3") == 0)
   1068   1.1  christos     return REG_R3;
   1069   1.1  christos   if (strcasecmp (name, "r4") == 0)
   1070   1.1  christos     return REG_R4;
   1071   1.1  christos   if (strcasecmp (name, "r5") == 0)
   1072   1.1  christos     return REG_R5;
   1073   1.1  christos   if (strcasecmp (name, "r6") == 0)
   1074   1.1  christos     return REG_R6;
   1075   1.1  christos   if (strcasecmp (name, "r7") == 0)
   1076   1.1  christos     return REG_R7;
   1077   1.1  christos   if (strcasecmp (name, "sp") == 0)
   1078   1.1  christos     return REG_SP_XG;
   1079   1.1  christos   if (strcasecmp (name, "pc") == 0)
   1080   1.1  christos     return REG_PC_XG;
   1081   1.1  christos   if (strcasecmp (name, "ccr") == 0)
   1082   1.1  christos     return REG_CCR_XG;
   1083   1.1  christos   return REG_NONE;
   1084   1.1  christos }
   1085  1.10  christos 
   1086   1.1  christos static char *
   1087   1.1  christos skip_whites (char *p)
   1088   1.1  christos {
   1089   1.1  christos   while (is_whitespace (*p))
   1090   1.1  christos     p++;
   1091   1.1  christos 
   1092   1.1  christos   return p;
   1093   1.1  christos }
   1094   1.1  christos 
   1095   1.1  christos /* Check the string at input_line_pointer
   1096   1.1  christos    to see if it is a valid register name.  */
   1097   1.1  christos static register_id
   1098   1.1  christos register_name (void)
   1099   1.1  christos {
   1100   1.1  christos   register_id reg_number;
   1101   1.1  christos   char c, *p = input_line_pointer;
   1102   1.1  christos 
   1103   1.1  christos   if (!is_name_beginner (*p++))
   1104   1.1  christos     return REG_NONE;
   1105   1.1  christos 
   1106   1.1  christos   while (is_part_of_name (*p++))
   1107   1.1  christos     continue;
   1108   1.1  christos 
   1109   1.1  christos   c = *--p;
   1110   1.1  christos   if (c)
   1111   1.1  christos     *p++ = 0;
   1112   1.1  christos 
   1113   1.1  christos   /* Look to see if it's in the register table.  */
   1114   1.1  christos   reg_number = reg_name_search (input_line_pointer);
   1115   1.1  christos   if (reg_number != REG_NONE)
   1116   1.1  christos     {
   1117   1.1  christos       if (c)
   1118   1.1  christos 	*--p = c;
   1119   1.1  christos 
   1120   1.1  christos       input_line_pointer = p;
   1121   1.1  christos       return reg_number;
   1122   1.1  christos     }
   1123   1.1  christos   if (c)
   1124   1.1  christos     *--p = c;
   1125   1.1  christos 
   1126   1.1  christos   return reg_number;
   1127   1.1  christos }
   1128   1.1  christos #define M6811_OP_CALL_ADDR    0x00800000
   1129   1.1  christos #define M6811_OP_PAGE_ADDR    0x04000000
   1130   1.1  christos 
   1131   1.1  christos /* Parse a string of operands and return an array of expressions.
   1132   1.1  christos 
   1133   1.1  christos    Operand      mode[0]         mode[1]       exp[0]       exp[1]
   1134   1.1  christos    #n           M6811_OP_IMM16  -             O_*
   1135   1.1  christos    *<exp>       M6811_OP_DIRECT -             O_*
   1136   1.1  christos    .{+-}<exp>   M6811_OP_JUMP_REL -           O_*
   1137   1.1  christos    <exp>        M6811_OP_IND16  -             O_*
   1138   1.1  christos    ,r N,r       M6812_OP_IDX    M6812_OP_REG  O_constant   O_register
   1139   1.1  christos    n,-r         M6812_PRE_DEC   M6812_OP_REG  O_constant   O_register
   1140   1.1  christos    n,+r         M6812_PRE_INC   " "
   1141   1.1  christos    n,r-         M6812_POST_DEC  " "
   1142   1.1  christos    n,r+         M6812_POST_INC  " "
   1143   1.1  christos    A,r B,r D,r  M6811_OP_REG    M6812_OP_REG  O_register   O_register
   1144   1.1  christos    [D,r]        M6811_OP_D_IDX  M6812_OP_REG  O_register   O_register
   1145   1.1  christos    [n,r]        M6811_OP_D_IDX_2 M6812_OP_REG  O_constant   O_register  */
   1146   1.1  christos static int
   1147   1.1  christos get_operand (operand *oper, int which, long opmode)
   1148   1.1  christos {
   1149   1.1  christos   char *p = input_line_pointer;
   1150   1.1  christos   int mode;
   1151   1.1  christos   register_id reg;
   1152   1.1  christos 
   1153   1.1  christos   oper->exp.X_op = O_absent;
   1154   1.1  christos   oper->reg1 = REG_NONE;
   1155   1.1  christos   oper->reg2 = REG_NONE;
   1156   1.1  christos   mode = M6811_OP_NONE;
   1157   1.1  christos 
   1158   1.1  christos   p = skip_whites (p);
   1159   1.1  christos 
   1160   1.1  christos   if (*p == 0 || *p == '\n' || *p == '\r')
   1161   1.1  christos     {
   1162   1.1  christos       input_line_pointer = p;
   1163   1.1  christos       return 0;
   1164   1.1  christos     }
   1165   1.1  christos 
   1166   1.1  christos   if (*p == '*' && (opmode & (M6811_OP_DIRECT | M6811_OP_IND16)))
   1167   1.1  christos     {
   1168   1.1  christos       mode = M6811_OP_DIRECT;
   1169   1.1  christos       p++;
   1170   1.1  christos     }
   1171   1.1  christos   else if (*p == '#')
   1172   1.1  christos     {
   1173   1.1  christos       if (!(opmode & (M6811_OP_IMM8 | M6811_OP_IMM16 | M6811_OP_BITMASK)))
   1174   1.1  christos 	{
   1175   1.1  christos 	  as_bad (_("Immediate operand is not allowed for operand %d."),
   1176   1.1  christos 		  which);
   1177   1.1  christos 	  return -1;
   1178   1.8  christos 	}
   1179   1.1  christos 
   1180   1.1  christos       mode = M6811_OP_IMM16;
   1181   1.1  christos       p++;
   1182   1.1  christos       if (startswith (p, "%hi"))
   1183   1.8  christos 	{
   1184   1.1  christos 	  p += 3;
   1185   1.1  christos 	  mode |= M6811_OP_HIGH_ADDR;
   1186   1.1  christos 	}
   1187   1.1  christos       else if (startswith (p, "%lo"))
   1188   1.1  christos 	{
   1189   1.1  christos 	  p += 3;
   1190   1.8  christos 	  mode |= M6811_OP_LOW_ADDR;
   1191   1.1  christos 	}
   1192   1.1  christos       /* %page modifier is used to obtain only the page number
   1193   1.1  christos          of the address of a function.  */
   1194   1.1  christos       else if (startswith (p, "%page"))
   1195   1.1  christos 	{
   1196   1.1  christos 	  p += 5;
   1197   1.1  christos 	  mode |= M6811_OP_PAGE_ADDR;
   1198   1.1  christos 	}
   1199   1.1  christos 
   1200   1.1  christos       /* %addr modifier is used to obtain the physical address part
   1201   1.8  christos          of the function (16-bit).  For 68HC12 the function will be
   1202   1.1  christos          mapped in the 16K window at 0x8000 and the value will be
   1203   1.1  christos          within that window (although the function address may not fit
   1204   1.1  christos          in 16-bit).  See bfd/elf32-m68hc12.c for the translation.  */
   1205   1.1  christos       else if (startswith (p, "%addr"))
   1206   1.1  christos 	{
   1207   1.1  christos 	  p += 5;
   1208   1.1  christos 	  mode |= M6811_OP_CALL_ADDR;
   1209   1.1  christos 	}
   1210   1.1  christos     }
   1211   1.1  christos   else if (*p == '.' && (p[1] == '+' || p[1] == '-'))
   1212   1.1  christos     {
   1213   1.1  christos       p++;
   1214   1.1  christos       mode = M6811_OP_JUMP_REL;
   1215   1.1  christos     }
   1216   1.1  christos   else if (*p == '[')
   1217   1.1  christos     {
   1218   1.1  christos       if (current_architecture & cpu6811)
   1219   1.1  christos 	as_bad (_("Indirect indexed addressing is not valid for 68HC11."));
   1220   1.1  christos 
   1221   1.1  christos       p++;
   1222   1.1  christos       mode = M6812_OP_D_IDX;
   1223   1.1  christos       p = skip_whites (p);
   1224   1.1  christos     }
   1225   1.1  christos   else if (*p == ',')		/* Special handling of ,x and ,y.  */
   1226   1.1  christos     {
   1227   1.1  christos       p++;
   1228   1.1  christos       input_line_pointer = p;
   1229   1.1  christos 
   1230   1.1  christos       reg = register_name ();
   1231   1.1  christos       if (reg != REG_NONE)
   1232   1.1  christos 	{
   1233   1.1  christos 	  oper->reg1 = reg;
   1234   1.1  christos 	  oper->exp.X_op = O_constant;
   1235   1.1  christos 	  oper->exp.X_add_number = 0;
   1236   1.1  christos 	  oper->mode = M6812_OP_IDX;
   1237   1.1  christos 	  return 1;
   1238   1.1  christos 	}
   1239   1.8  christos       as_bad (_("Spurious `,' or bad indirect register addressing mode."));
   1240   1.1  christos       return -1;
   1241   1.1  christos     }
   1242   1.1  christos   /* Handle 68HC12 page specification in 'call foo,%page(bar)'.  */
   1243   1.1  christos   else if ((opmode & M6812_OP_PAGE) && startswith (p, "%page"))
   1244   1.1  christos     {
   1245   1.1  christos       p += 5;
   1246   1.1  christos       mode = M6811_OP_PAGE_ADDR | M6812_OP_PAGE | M6811_OP_IND16;
   1247   1.1  christos     }
   1248   1.1  christos   input_line_pointer = p;
   1249   1.1  christos 
   1250   1.1  christos   if (mode == M6811_OP_NONE || mode == M6812_OP_D_IDX)
   1251   1.1  christos     reg = register_name ();
   1252   1.1  christos   else
   1253   1.1  christos     reg = REG_NONE;
   1254   1.1  christos 
   1255   1.1  christos   if (reg != REG_NONE)
   1256   1.1  christos     {
   1257   1.1  christos       p = skip_whites (input_line_pointer);
   1258   1.1  christos       if (*p == ']' && mode == M6812_OP_D_IDX)
   1259   1.1  christos 	{
   1260   1.1  christos 	  as_bad
   1261   1.1  christos 	    (_("Missing second register or offset for indexed-indirect mode."));
   1262   1.1  christos 	  return -1;
   1263   1.1  christos 	}
   1264   1.1  christos 
   1265   1.1  christos       oper->reg1 = reg;
   1266   1.1  christos       oper->mode = mode | M6812_OP_REG;
   1267   1.1  christos       if (*p != ',')
   1268   1.1  christos 	{
   1269   1.1  christos 	  if (mode == M6812_OP_D_IDX)
   1270   1.1  christos 	    {
   1271   1.1  christos 	      as_bad (_("Missing second register for indexed-indirect mode."));
   1272   1.1  christos 	      return -1;
   1273   1.1  christos 	    }
   1274   1.1  christos 	  return 1;
   1275   1.1  christos 	}
   1276   1.1  christos 
   1277   1.1  christos       p++;
   1278   1.1  christos       input_line_pointer = p;
   1279   1.1  christos       reg = register_name ();
   1280   1.1  christos       if (reg != REG_NONE)
   1281   1.1  christos 	{
   1282   1.1  christos 	  p = skip_whites (input_line_pointer);
   1283   1.1  christos 	  if (mode == M6812_OP_D_IDX)
   1284   1.1  christos 	    {
   1285   1.1  christos 	      if (*p != ']')
   1286   1.1  christos 		{
   1287   1.1  christos 		  as_bad (_("Missing `]' to close indexed-indirect mode."));
   1288   1.1  christos 		  return -1;
   1289   1.1  christos 		}
   1290   1.1  christos 	      p++;
   1291   1.1  christos               oper->mode = M6812_OP_D_IDX;
   1292   1.1  christos 	    }
   1293   1.1  christos 	  input_line_pointer = p;
   1294   1.1  christos 
   1295   1.1  christos 	  oper->reg2 = reg;
   1296   1.1  christos 	  return 1;
   1297   1.1  christos 	}
   1298   1.1  christos       return 1;
   1299   1.1  christos     }
   1300   1.1  christos 
   1301   1.1  christos   /* In MRI mode, isolate the operand because we can't distinguish
   1302   1.1  christos      operands from comments.  */
   1303   1.1  christos   if (flag_mri)
   1304  1.10  christos     {
   1305   1.1  christos       char c = 0;
   1306   1.1  christos 
   1307   1.1  christos       p = skip_whites (p);
   1308   1.1  christos       while (*p && !is_whitespace (*p))
   1309   1.1  christos 	p++;
   1310   1.1  christos 
   1311   1.1  christos       if (*p)
   1312   1.1  christos 	{
   1313   1.1  christos 	  c = *p;
   1314   1.1  christos 	  *p = 0;
   1315   1.1  christos 	}
   1316   1.1  christos 
   1317   1.1  christos       /* Parse as an expression.  */
   1318   1.1  christos       expression (&oper->exp);
   1319   1.1  christos 
   1320   1.1  christos       if (c)
   1321   1.1  christos 	{
   1322   1.1  christos 	  *p = c;
   1323   1.1  christos 	}
   1324   1.1  christos     }
   1325   1.1  christos   else
   1326   1.1  christos     {
   1327   1.1  christos       expression (&oper->exp);
   1328   1.1  christos     }
   1329   1.1  christos 
   1330   1.1  christos   if (oper->exp.X_op == O_illegal)
   1331   1.1  christos     {
   1332   1.1  christos       as_bad (_("Illegal operand."));
   1333   1.1  christos       return -1;
   1334   1.1  christos     }
   1335   1.1  christos   else if (oper->exp.X_op == O_absent)
   1336   1.1  christos     {
   1337   1.1  christos       as_bad (_("Missing operand."));
   1338   1.1  christos       return -1;
   1339   1.1  christos     }
   1340   1.1  christos 
   1341   1.1  christos   p = input_line_pointer;
   1342   1.1  christos 
   1343   1.1  christos   if (mode == M6811_OP_NONE || mode == M6811_OP_DIRECT
   1344   1.1  christos       || mode == M6812_OP_D_IDX)
   1345   1.1  christos     {
   1346   1.1  christos       p = skip_whites (input_line_pointer);
   1347   1.1  christos 
   1348   1.1  christos       if (*p == ',')
   1349   1.1  christos 	{
   1350   1.1  christos 	  int possible_mode = M6811_OP_NONE;
   1351   1.1  christos 	  char *old_input_line;
   1352   1.1  christos 
   1353   1.1  christos 	  old_input_line = p;
   1354   1.1  christos 	  p++;
   1355   1.1  christos 
   1356   1.1  christos 	  /* 68HC12 pre increment or decrement.  */
   1357   1.1  christos 	  if (mode == M6811_OP_NONE)
   1358   1.1  christos 	    {
   1359   1.1  christos 	      if (*p == '-')
   1360   1.1  christos 		{
   1361   1.1  christos 		  possible_mode = M6812_PRE_DEC;
   1362   1.1  christos 		  p++;
   1363   1.1  christos 		}
   1364   1.1  christos 	      else if (*p == '+')
   1365   1.1  christos 		{
   1366   1.1  christos 		  possible_mode = M6812_PRE_INC;
   1367   1.1  christos 		  p++;
   1368   1.1  christos 		}
   1369   1.1  christos 	      p = skip_whites (p);
   1370   1.1  christos 	    }
   1371   1.1  christos 	  input_line_pointer = p;
   1372   1.1  christos 	  reg = register_name ();
   1373   1.1  christos 
   1374   1.1  christos 	  /* Backtrack if we have a valid constant expression and
   1375   1.1  christos 	     it does not correspond to the offset of the 68HC12 indexed
   1376   1.1  christos 	     addressing mode (as in N,x).  */
   1377   1.1  christos 	  if (reg == REG_NONE && mode == M6811_OP_NONE
   1378   1.1  christos 	      && possible_mode != M6811_OP_NONE)
   1379   1.1  christos 	    {
   1380   1.1  christos 	      oper->mode = M6811_OP_IND16 | M6811_OP_JUMP_REL;
   1381   1.1  christos 	      input_line_pointer = skip_whites (old_input_line);
   1382   1.1  christos 	      return 1;
   1383   1.1  christos 	    }
   1384   1.1  christos 
   1385   1.1  christos 	  if (possible_mode != M6811_OP_NONE)
   1386   1.1  christos 	    mode = possible_mode;
   1387   1.1  christos 
   1388   1.1  christos 	  if ((current_architecture & cpu6811)
   1389   1.1  christos 	      && possible_mode != M6811_OP_NONE)
   1390   1.1  christos 	    as_bad (_("Pre-increment mode is not valid for 68HC11"));
   1391   1.1  christos 	  /* Backtrack.  */
   1392   1.1  christos 	  if (which == 0 && opmode & M6812_OP_IDX_P2
   1393   1.1  christos 	      && reg != REG_X && reg != REG_Y
   1394   1.1  christos 	      && reg != REG_PC && reg != REG_SP)
   1395   1.1  christos 	    {
   1396   1.1  christos 	      reg = REG_NONE;
   1397   1.1  christos 	      input_line_pointer = p;
   1398   1.1  christos 	    }
   1399   1.1  christos 
   1400   1.1  christos 	  if (reg == REG_NONE && mode != M6811_OP_DIRECT
   1401   1.1  christos 	      && !(mode == M6811_OP_NONE && opmode & M6811_OP_IND16))
   1402   1.1  christos 	    {
   1403   1.1  christos 	      as_bad (_("Wrong register in register indirect mode."));
   1404   1.1  christos 	      return -1;
   1405   1.1  christos 	    }
   1406   1.1  christos 	  if (mode == M6812_OP_D_IDX)
   1407   1.1  christos 	    {
   1408   1.1  christos 	      p = skip_whites (input_line_pointer);
   1409   1.1  christos 	      if (*p++ != ']')
   1410   1.1  christos 		{
   1411   1.1  christos 		  as_bad (_("Missing `]' to close register indirect operand."));
   1412   1.1  christos 		  return -1;
   1413   1.1  christos 		}
   1414   1.1  christos 	      input_line_pointer = p;
   1415   1.1  christos               oper->reg1 = reg;
   1416   1.1  christos               oper->mode = M6812_OP_D_IDX_2;
   1417   1.1  christos               return 1;
   1418   1.1  christos 	    }
   1419   1.1  christos 	  if (reg != REG_NONE)
   1420   1.1  christos 	    {
   1421   1.1  christos 	      oper->reg1 = reg;
   1422   1.1  christos 	      if (mode == M6811_OP_NONE)
   1423   1.1  christos 		{
   1424   1.1  christos 		  p = input_line_pointer;
   1425   1.1  christos 		  if (*p == '-')
   1426   1.1  christos 		    {
   1427   1.1  christos 		      mode = M6812_POST_DEC;
   1428   1.1  christos 		      p++;
   1429   1.1  christos 		      if (current_architecture & cpu6811)
   1430   1.1  christos 			as_bad
   1431   1.1  christos 			  (_("Post-decrement mode is not valid for 68HC11."));
   1432   1.1  christos 		    }
   1433   1.1  christos 		  else if (*p == '+')
   1434   1.1  christos 		    {
   1435   1.1  christos 		      mode = M6812_POST_INC;
   1436   1.1  christos 		      p++;
   1437   1.1  christos 		      if (current_architecture & cpu6811)
   1438   1.1  christos 			as_bad
   1439   1.1  christos 			  (_("Post-increment mode is not valid for 68HC11."));
   1440   1.1  christos 		    }
   1441   1.1  christos 		  else
   1442   1.1  christos 		    mode = M6812_OP_IDX;
   1443   1.1  christos 
   1444   1.1  christos 		  input_line_pointer = p;
   1445   1.1  christos 		}
   1446   1.1  christos 	      else
   1447   1.1  christos 		mode |= M6812_OP_IDX;
   1448   1.1  christos 
   1449   1.1  christos 	      oper->mode = mode;
   1450   1.1  christos 	      return 1;
   1451   1.1  christos 	    }
   1452   1.1  christos           input_line_pointer = old_input_line;
   1453   1.1  christos 	}
   1454   1.1  christos 
   1455   1.1  christos       if (mode == M6812_OP_D_IDX_2)
   1456   1.1  christos 	{
   1457   1.1  christos 	  as_bad (_("Invalid indexed indirect mode."));
   1458   1.1  christos 	  return -1;
   1459   1.1  christos 	}
   1460   1.1  christos     }
   1461   1.1  christos 
   1462   1.1  christos   /* If the mode is not known until now, this is either a label
   1463   1.1  christos      or an indirect address.  */
   1464  1.10  christos   if (mode == M6811_OP_NONE)
   1465   1.1  christos     mode = M6811_OP_IND16 | M6811_OP_JUMP_REL;
   1466   1.1  christos 
   1467   1.1  christos   p = input_line_pointer;
   1468   1.1  christos   while (is_whitespace (*p))
   1469   1.1  christos     p++;
   1470   1.1  christos   input_line_pointer = p;
   1471   1.1  christos   oper->mode = mode;
   1472   1.1  christos 
   1473   1.1  christos   return 1;
   1474   1.1  christos }
   1475   1.1  christos 
   1476   1.1  christos #define M6812_AUTO_INC_DEC (M6812_PRE_INC | M6812_PRE_DEC \
   1477   1.1  christos                             | M6812_POST_INC | M6812_POST_DEC)
   1478   1.1  christos 
   1479   1.1  christos /* Checks that the number 'num' fits for a given mode.  */
   1480   1.1  christos static int
   1481   1.1  christos check_range (long num, int mode)
   1482   1.1  christos {
   1483   1.1  christos   if (current_architecture == cpuxgate)
   1484   1.1  christos     {
   1485   1.1  christos       switch (mode)
   1486   1.1  christos 	{
   1487   1.1  christos 	case M68XG_OP_IMM3:
   1488   1.1  christos 	  return (num >= 0 && num <= 7) ? 1 : 0;
   1489   1.1  christos 
   1490   1.1  christos 	case M68XG_OP_R_IMM4:
   1491   1.1  christos 	  return (num >= 0 && num <= 15) ? 1 : 0;
   1492   1.1  christos 
   1493   1.1  christos 	case M68XG_OP_R_R_OFFS5:
   1494   1.1  christos 	  return (num >= 0 && num <= 31) ? 1 : 0;
   1495   1.1  christos 
   1496   1.1  christos 	case M68XG_OP_R_IMM8:
   1497   1.1  christos 	  return (num >= 0 && num <= 255) ? 1 : 0;
   1498   1.1  christos 
   1499   1.1  christos 	case M68XG_OP_R_IMM16:
   1500   1.1  christos 	  return (num >= 0 && num <= 65535) ? 1 : 0;
   1501   1.1  christos 
   1502   1.1  christos 	case M68XG_OP_B_MARKER:
   1503   1.1  christos 	  return (num >= -512 && num <= 511) ? 1 : 0;
   1504   1.1  christos 
   1505   1.1  christos 	case M68XG_OP_BRA_MARKER:
   1506   1.1  christos 	  return (num >= -1024 && num <= 1023) ? 1 : 0;
   1507   1.1  christos 
   1508   1.1  christos 	default:
   1509   1.1  christos 	  return 0;
   1510   1.1  christos 	}
   1511   1.1  christos     }
   1512   1.1  christos   else
   1513   1.1  christos     {
   1514   1.1  christos       /* Auto increment and decrement are ok for [-8..8] without 0.  */
   1515   1.1  christos       if (mode & M6812_AUTO_INC_DEC)
   1516   1.1  christos 	return (num != 0 && num <= 8 && num >= -8);
   1517   1.1  christos 
   1518   1.1  christos       /* The 68HC12 supports 5, 9 and 16-bit offsets.  */
   1519   1.1  christos       if (mode & (M6812_INDEXED_IND | M6812_INDEXED | M6812_OP_IDX))
   1520   1.1  christos 	mode = M6811_OP_IND16;
   1521   1.1  christos 
   1522   1.1  christos       if (mode & M6812_OP_JUMP_REL16)
   1523   1.1  christos 	mode = M6811_OP_IND16;
   1524   1.1  christos 
   1525   1.1  christos       mode &= ~M6811_OP_BRANCH;
   1526   1.1  christos       switch (mode)
   1527   1.1  christos 	{
   1528   1.1  christos 	case M6811_OP_IX:
   1529   1.1  christos 	case M6811_OP_IY:
   1530   1.1  christos 	case M6811_OP_DIRECT:
   1531   1.1  christos 	  return (num >= 0 && num <= 255) ? 1 : 0;
   1532   1.1  christos 
   1533   1.1  christos 	case M6811_OP_BITMASK:
   1534   1.1  christos 	case M6811_OP_IMM8:
   1535   1.1  christos 	case M6812_OP_PAGE:
   1536   1.1  christos 	  return (((num & 0xFFFFFF00) == 0) || ((num & 0xFFFFFF00) == 0xFFFFFF00))
   1537   1.1  christos 	    ? 1 : 0;
   1538   1.1  christos 
   1539   1.1  christos 	case M6811_OP_JUMP_REL:
   1540   1.1  christos 	  return (num >= -128 && num <= 127) ? 1 : 0;
   1541   1.1  christos 
   1542   1.1  christos 	case M6811_OP_IND16:
   1543   1.1  christos 	case M6811_OP_IND16 | M6812_OP_PAGE:
   1544   1.1  christos 	case M6811_OP_IMM16:
   1545   1.1  christos 	  return (((num & 0xFFFF0000) == 0) || ((num & 0xFFFF0000) == 0xFFFF0000))
   1546   1.1  christos 	    ? 1 : 0;
   1547   1.1  christos 
   1548   1.1  christos 	case M6812_OP_IBCC_MARKER:
   1549   1.1  christos 	case M6812_OP_TBCC_MARKER:
   1550   1.1  christos 	case M6812_OP_DBCC_MARKER:
   1551   1.1  christos 	  return (num >= -256 && num <= 255) ? 1 : 0;
   1552   1.1  christos 
   1553   1.1  christos 	case M6812_OP_TRAP_ID:
   1554   1.1  christos 	  return ((num >= 0x30 && num <= 0x39)
   1555   1.1  christos 		  || (num >= 0x40 && num <= 0x0ff)) ? 1 : 0;
   1556   1.1  christos 
   1557   1.1  christos 	default:
   1558   1.1  christos 	  return 0;
   1559   1.1  christos 	}
   1560   1.1  christos     }
   1561   1.1  christos }
   1562   1.1  christos 
   1563   1.1  christos /* Gas fixup generation.  */
   1565   1.1  christos 
   1566   1.1  christos /* Put a 1 byte expression described by 'oper'.  If this expression contains
   1567   1.1  christos    unresolved symbols, generate an 8-bit fixup.  */
   1568   1.1  christos static void
   1569   1.1  christos fixup8 (expressionS *oper, int mode, int opmode)
   1570   1.1  christos {
   1571   1.1  christos   char *f;
   1572   1.1  christos 
   1573   1.1  christos   f = frag_more (1);
   1574   1.1  christos 
   1575   1.1  christos   if (oper->X_op == O_constant)
   1576   1.1  christos     {
   1577   1.9  christos       if (mode & M6812_OP_TRAP_ID
   1578   1.9  christos 	  && !check_range (oper->X_add_number, M6812_OP_TRAP_ID))
   1579   1.1  christos 	{
   1580   1.1  christos 	  static char trap_id_warn_once = 0;
   1581   1.1  christos 
   1582   1.1  christos 	  as_bad (_("Trap id `%" PRId64 "' is out of range."),
   1583   1.1  christos 		  (int64_t) oper->X_add_number);
   1584   1.1  christos 	  if (trap_id_warn_once == 0)
   1585   1.1  christos 	    {
   1586   1.1  christos 	      trap_id_warn_once = 1;
   1587   1.1  christos 	      as_bad (_("Trap id must be within [0x30..0x39] or [0x40..0xff]."));
   1588   1.1  christos 	    }
   1589   1.9  christos 	}
   1590   1.9  christos 
   1591   1.1  christos       if (!(mode & M6812_OP_TRAP_ID)
   1592   1.1  christos 	  && !check_range (oper->X_add_number, mode))
   1593   1.1  christos 	{
   1594   1.1  christos 	  as_bad (_("Operand out of 8-bit range: `%" PRId64 "'."),
   1595   1.1  christos 		  (int64_t) oper->X_add_number);
   1596   1.1  christos 	}
   1597   1.1  christos       number_to_chars_bigendian (f, oper->X_add_number & 0x0FF, 1);
   1598   1.1  christos     }
   1599   1.1  christos   else if (oper->X_op != O_register)
   1600   1.1  christos     {
   1601   1.3  christos       if (mode & M6812_OP_TRAP_ID)
   1602   1.8  christos 	as_bad (_("The trap id must be a constant."));
   1603   1.1  christos 
   1604   1.1  christos       if (mode == M6811_OP_JUMP_REL)
   1605   1.1  christos 	{
   1606   1.1  christos 	  fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
   1607   1.5  christos 		       oper, true, BFD_RELOC_8_PCREL);
   1608   1.1  christos 	}
   1609   1.1  christos       else
   1610   1.1  christos 	{
   1611   1.1  christos 	  fixS *fixp;
   1612   1.1  christos           bfd_reloc_code_real_type reloc;
   1613   1.1  christos 
   1614   1.1  christos 	  /* Now create an 8-bit fixup.  If there was some %hi, %lo
   1615   1.1  christos 	     or %page modifier, generate the reloc accordingly.  */
   1616   1.1  christos           if (opmode & M6811_OP_HIGH_ADDR)
   1617   1.1  christos             reloc = BFD_RELOC_M68HC11_HI8;
   1618   1.1  christos           else if (opmode & M6811_OP_LOW_ADDR)
   1619   1.1  christos             reloc = BFD_RELOC_M68HC11_LO8;
   1620   1.1  christos           else if (opmode & M6811_OP_PAGE_ADDR)
   1621   1.8  christos             reloc = BFD_RELOC_M68HC11_PAGE;
   1622   1.1  christos           else
   1623   1.1  christos             reloc = BFD_RELOC_8;
   1624   1.1  christos 
   1625   1.1  christos 	  fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
   1626   1.1  christos                               oper, false, reloc);
   1627   1.1  christos           if (reloc != BFD_RELOC_8)
   1628   1.1  christos             fixp->fx_no_overflow = 1;
   1629   1.1  christos 	}
   1630   1.1  christos       number_to_chars_bigendian (f, 0, 1);
   1631   1.1  christos     }
   1632   1.1  christos   else
   1633   1.1  christos     {
   1634   1.1  christos       as_fatal (_("Operand `%x' not recognized in fixup8."), oper->X_op);
   1635   1.1  christos     }
   1636   1.1  christos }
   1637   1.1  christos 
   1638   1.1  christos /* Put a 2 byte expression described by 'oper'.  If this expression contains
   1639   1.1  christos    unresolved symbols, generate a 16-bit fixup.  */
   1640   1.1  christos static void
   1641   1.1  christos fixup16 (expressionS *oper, int mode, int opmode ATTRIBUTE_UNUSED)
   1642   1.1  christos {
   1643   1.1  christos   char *f;
   1644   1.1  christos 
   1645   1.1  christos   f = frag_more (2);
   1646   1.9  christos 
   1647   1.9  christos   if (oper->X_op == O_constant)
   1648   1.1  christos     {
   1649   1.1  christos       if (!check_range (oper->X_add_number, mode))
   1650   1.1  christos 	{
   1651   1.1  christos 	  as_bad (_("Operand out of 16-bit range: `%" PRId64 "'."),
   1652   1.1  christos 		  (int64_t) oper->X_add_number);
   1653   1.1  christos 	}
   1654   1.5  christos       number_to_chars_bigendian (f, oper->X_add_number & 0x0FFFF, 2);
   1655   1.1  christos     }
   1656   1.1  christos   else if (oper->X_op != O_register)
   1657   1.1  christos     {
   1658   1.1  christos       fixS *fixp;
   1659   1.1  christos       bfd_reloc_code_real_type reloc;
   1660   1.1  christos 
   1661   1.1  christos       if ((opmode & M6811_OP_CALL_ADDR) && (mode & M6811_OP_IMM16))
   1662   1.1  christos         reloc = BFD_RELOC_M68HC11_LO16;
   1663   1.1  christos       else if (mode & M6812_OP_JUMP_REL16)
   1664   1.1  christos         reloc = BFD_RELOC_16_PCREL;
   1665   1.1  christos       else if (mode & M6812_OP_PAGE)
   1666   1.1  christos         reloc = BFD_RELOC_M68HC11_LO16;
   1667   1.1  christos       else
   1668   1.1  christos         reloc = BFD_RELOC_16;
   1669   1.1  christos 
   1670   1.1  christos       /* Now create a 16-bit fixup.  */
   1671   1.3  christos       fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 2,
   1672   1.1  christos 			  oper,
   1673   1.1  christos 			  reloc == BFD_RELOC_16_PCREL,
   1674   1.1  christos                           reloc);
   1675   1.1  christos       number_to_chars_bigendian (f, 0, 2);
   1676   1.1  christos 
   1677   1.1  christos       if (reloc == BFD_RELOC_M68HC11_LO16)
   1678   1.1  christos         fixp->fx_no_overflow = 1;
   1679   1.1  christos     }
   1680   1.1  christos   else
   1681   1.1  christos     {
   1682   1.1  christos       as_fatal (_("Operand `%x' not recognized in fixup16."), oper->X_op);
   1683   1.1  christos     }
   1684   1.1  christos }
   1685   1.1  christos 
   1686   1.1  christos /* Put a 3 byte expression described by 'oper'.  If this expression contains
   1687   1.1  christos    unresolved symbols, generate a 24-bit fixup.  */
   1688   1.1  christos static void
   1689   1.1  christos fixup24 (expressionS *oper, int mode, int opmode ATTRIBUTE_UNUSED)
   1690   1.1  christos {
   1691   1.1  christos   char *f;
   1692   1.1  christos 
   1693   1.1  christos   f = frag_more (3);
   1694   1.9  christos 
   1695   1.9  christos   if (oper->X_op == O_constant)
   1696   1.1  christos     {
   1697   1.1  christos       if (!check_range (oper->X_add_number, mode))
   1698   1.1  christos 	{
   1699   1.1  christos 	  as_bad (_("Operand out of 16-bit range: `%" PRId64 "'."),
   1700   1.1  christos 		  (int64_t) oper->X_add_number);
   1701   1.1  christos 	}
   1702   1.1  christos       number_to_chars_bigendian (f, oper->X_add_number & 0x0FFFFFF, 3);
   1703   1.8  christos     }
   1704   1.1  christos   else if (oper->X_op != O_register)
   1705   1.1  christos     {
   1706   1.1  christos       /* Now create a 24-bit fixup.  */
   1707   1.1  christos       fix_new_exp (frag_now, f - frag_now->fr_literal, 3,
   1708   1.1  christos 		   oper, false, BFD_RELOC_M68HC11_24);
   1709   1.1  christos       number_to_chars_bigendian (f, 0, 3);
   1710   1.1  christos     }
   1711   1.1  christos   else
   1712   1.1  christos     {
   1713   1.6  christos       as_fatal (_("Operand `%x' not recognized in fixup16."), oper->X_op);
   1714   1.1  christos     }
   1715   1.1  christos }
   1716   1.1  christos 
   1717   1.1  christos /* XGATE Put a 1 byte expression described by 'oper'.  If this expression
   1718   1.1  christos    contains unresolved symbols, generate an 8-bit fixup.  */
   1719   1.1  christos static void
   1720   1.1  christos fixup8_xg (expressionS *oper, int mode, int opmode)
   1721   1.1  christos {
   1722   1.1  christos   char *f;
   1723   1.1  christos 
   1724   1.5  christos   f = frag_more (1);
   1725   1.1  christos 
   1726   1.1  christos   if (oper->X_op == O_constant)
   1727   1.1  christos     {
   1728   1.1  christos       fixS *fixp;
   1729   1.1  christos       bfd_reloc_code_real_type reloc;
   1730   1.1  christos 
   1731   1.1  christos       if ((opmode & M6811_OP_HIGH_ADDR) || (opmode & M6811_OP_LOW_ADDR))
   1732   1.1  christos         {
   1733   1.1  christos           if (opmode & M6811_OP_HIGH_ADDR)
   1734   1.8  christos             reloc = BFD_RELOC_M68HC11_HI8;
   1735   1.1  christos           else
   1736   1.1  christos             reloc = BFD_RELOC_M68HC11_LO8;
   1737   1.1  christos 
   1738   1.1  christos           fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
   1739   1.1  christos 			      oper, false, reloc);
   1740   1.1  christos           fixp->fx_no_overflow = 1;
   1741   1.9  christos           number_to_chars_bigendian (f, 0, 1);
   1742   1.9  christos         }
   1743   1.1  christos      else
   1744   1.1  christos         {
   1745   1.1  christos 	  if (!(check_range (oper->X_add_number, mode)))
   1746   1.1  christos 	    as_bad (_("Operand out of 8-bit range: `%" PRId64 "'."),
   1747   1.1  christos 		    (int64_t) oper->X_add_number);
   1748   1.1  christos           number_to_chars_bigendian (f, oper->X_add_number & 0x0FF, 1);
   1749   1.1  christos         }
   1750   1.1  christos     }
   1751   1.1  christos   else if (oper->X_op != O_register)
   1752   1.3  christos     {
   1753   1.8  christos       if (mode == M68XG_OP_REL9)
   1754   1.1  christos         {
   1755   1.1  christos           /* Future improvement:
   1756   1.1  christos 	     This fixup/reloc isn't adding on constants to symbols.  */
   1757   1.1  christos           fix_new_exp (frag_now, f - frag_now->fr_literal -1, 2,
   1758   1.1  christos 		       oper, true, BFD_RELOC_M68HC12_9_PCREL);
   1759   1.3  christos       	}
   1760   1.8  christos       else if (mode == M68XG_OP_REL10)
   1761   1.1  christos         {
   1762   1.1  christos           /* Future improvement:
   1763   1.1  christos 	     This fixup/reloc isn't adding on constants to symbols.  */
   1764   1.1  christos           fix_new_exp (frag_now, f - frag_now->fr_literal -1, 2,
   1765   1.5  christos     	               oper, true, BFD_RELOC_M68HC12_10_PCREL);
   1766   1.1  christos         }
   1767   1.1  christos       else
   1768   1.1  christos         {
   1769   1.1  christos           fixS *fixp;
   1770   1.1  christos           bfd_reloc_code_real_type reloc;
   1771   1.1  christos 
   1772   1.1  christos           /* Now create an 8-bit fixup.  If there was some %hi, %lo
   1773   1.1  christos              modifier, generate the reloc accordingly.  */
   1774   1.1  christos           if (opmode & M6811_OP_HIGH_ADDR)
   1775   1.1  christos             reloc = BFD_RELOC_M68HC11_HI8;
   1776   1.1  christos           else if (opmode & M6811_OP_LOW_ADDR)
   1777   1.8  christos             reloc = BFD_RELOC_M68HC11_LO8;
   1778   1.1  christos           else
   1779   1.1  christos             reloc = BFD_RELOC_8;
   1780   1.1  christos 
   1781   1.1  christos           fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
   1782   1.1  christos             oper, false, reloc);
   1783   1.1  christos           if (reloc != BFD_RELOC_8)
   1784   1.1  christos               fixp->fx_no_overflow = 1;
   1785   1.1  christos         }
   1786   1.1  christos       number_to_chars_bigendian (f, 0, 1);
   1787   1.1  christos     }
   1788   1.1  christos   else
   1789   1.1  christos     as_fatal (_("Operand `%x' not recognized in fixup8."), oper->X_op);
   1790   1.1  christos }
   1791   1.1  christos 
   1792   1.1  christos /* 68HC11 and 68HC12 code generation.  */
   1794   1.1  christos 
   1795   1.1  christos /* Translate the short branch/bsr instruction into a long branch.  */
   1796   1.1  christos 
   1797   1.1  christos static unsigned char
   1798   1.1  christos convert_branch (unsigned char code)
   1799   1.1  christos {
   1800   1.1  christos   if (IS_OPCODE (code, M6812_BSR))
   1801   1.1  christos     return M6812_JSR;
   1802   1.1  christos   else if (IS_OPCODE (code, M6811_BSR))
   1803   1.1  christos     return M6811_JSR;
   1804   1.1  christos   else if (IS_OPCODE (code, M6811_BRA))
   1805   1.1  christos     return (current_architecture & cpu6812) ? M6812_JMP : M6811_JMP;
   1806   1.1  christos   else
   1807   1.1  christos     as_fatal (_("Unexpected branch conversion with `%x'"), code);
   1808   1.1  christos 
   1809   1.1  christos   /* Keep gcc happy.  */
   1810   1.1  christos   return M6811_JSR;
   1811   1.1  christos }
   1812   1.1  christos 
   1813   1.1  christos /* Start a new insn that contains at least 'size' bytes.  Record the
   1814   1.1  christos    line information of that insn in the dwarf2 debug sections.  */
   1815   1.1  christos static char *
   1816   1.1  christos m68hc11_new_insn (int size)
   1817   1.1  christos {
   1818   1.1  christos   char *f;
   1819   1.1  christos 
   1820   1.1  christos   f = frag_more (size);
   1821   1.1  christos 
   1822   1.1  christos   dwarf2_emit_insn (size);
   1823   1.1  christos 
   1824   1.1  christos   return f;
   1825   1.1  christos }
   1826   1.1  christos 
   1827   1.1  christos /* Builds a jump instruction (bra, bcc, bsr).  */
   1828   1.1  christos static void
   1829   1.1  christos build_jump_insn (struct m68hc11_opcode *opcode, operand operands[],
   1830   1.1  christos                  int nb_operands, int jmp_mode)
   1831   1.1  christos {
   1832   1.1  christos   unsigned char code;
   1833   1.1  christos   char *f;
   1834   1.1  christos   unsigned long n;
   1835   1.1  christos 
   1836   1.1  christos   /* The relative branch conversion is not supported for
   1837   1.1  christos      brclr and brset.  */
   1838   1.1  christos   gas_assert ((opcode->format & M6811_OP_BITMASK) == 0);
   1839   1.1  christos   gas_assert (nb_operands == 1);
   1840   1.1  christos   gas_assert (operands[0].reg1 == REG_NONE && operands[0].reg2 == REG_NONE);
   1841   1.1  christos 
   1842   1.1  christos   code = opcode->opcode;
   1843   1.1  christos 
   1844   1.1  christos   n = operands[0].exp.X_add_number;
   1845   1.1  christos 
   1846   1.1  christos   /* Turn into a long branch:
   1847   1.1  christos      - when force long branch option (and not for jbcc pseudos),
   1848   1.1  christos      - when jbcc and the constant is out of -128..127 range,
   1849   1.1  christos      - when branch optimization is allowed and branch out of range.  */
   1850   1.1  christos   if ((jmp_mode == 0 && flag_force_long_jumps)
   1851   1.1  christos       || (operands[0].exp.X_op == O_constant
   1852   1.1  christos 	  && (!check_range (n, opcode->format) &&
   1853   1.1  christos 	      (jmp_mode == 1 || flag_fixed_branches == 0))))
   1854   1.1  christos     {
   1855   1.1  christos       fix_new (frag_now, frag_now_fix (), 0,
   1856   1.1  christos                &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
   1857   1.1  christos 
   1858   1.1  christos       if (code == M6811_BSR || code == M6811_BRA || code == M6812_BSR)
   1859   1.1  christos 	{
   1860   1.1  christos 	  code = convert_branch (code);
   1861   1.1  christos 
   1862   1.1  christos 	  f = m68hc11_new_insn (1);
   1863   1.1  christos 	  number_to_chars_bigendian (f, code, 1);
   1864   1.1  christos 	}
   1865   1.1  christos       else if (current_architecture & cpu6812)
   1866   1.1  christos 	{
   1867   1.1  christos 	  /* 68HC12: translate the bcc into a lbcc.  */
   1868   1.1  christos 	  f = m68hc11_new_insn (2);
   1869   1.1  christos 	  number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1);
   1870   1.1  christos 	  number_to_chars_bigendian (f + 1, code, 1);
   1871   1.1  christos 	  fixup16 (&operands[0].exp, M6812_OP_JUMP_REL16,
   1872   1.1  christos 		   M6812_OP_JUMP_REL16);
   1873   1.1  christos 	  return;
   1874   1.1  christos 	}
   1875   1.1  christos       else
   1876   1.1  christos 	{
   1877   1.1  christos 	  /* 68HC11: translate the bcc into b!cc +3; jmp <L>.  */
   1878   1.1  christos 	  f = m68hc11_new_insn (3);
   1879   1.1  christos 	  code ^= 1;
   1880   1.1  christos 	  number_to_chars_bigendian (f, code, 1);
   1881   1.1  christos 	  number_to_chars_bigendian (f + 1, 3, 1);
   1882   1.1  christos 	  number_to_chars_bigendian (f + 2, M6811_JMP, 1);
   1883   1.1  christos 	}
   1884   1.1  christos       fixup16 (&operands[0].exp, M6811_OP_IND16, M6811_OP_IND16);
   1885   1.1  christos       return;
   1886   1.1  christos     }
   1887   1.1  christos 
   1888   1.1  christos   /* Branch with a constant that must fit in 8-bits.  */
   1889   1.1  christos   if (operands[0].exp.X_op == O_constant)
   1890   1.1  christos     {
   1891   1.1  christos       if (!check_range (n, opcode->format))
   1892   1.1  christos 	{
   1893   1.1  christos 	  as_bad (_("Operand out of range for a relative branch: `%ld'"),
   1894   1.1  christos                   n);
   1895   1.1  christos 	}
   1896   1.1  christos       else if (opcode->format & M6812_OP_JUMP_REL16)
   1897   1.1  christos 	{
   1898   1.1  christos 	  f = m68hc11_new_insn (4);
   1899   1.1  christos 	  number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1);
   1900   1.1  christos 	  number_to_chars_bigendian (f + 1, code, 1);
   1901   1.1  christos 	  number_to_chars_bigendian (f + 2, n & 0x0ffff, 2);
   1902   1.1  christos 	}
   1903   1.1  christos       else
   1904   1.1  christos 	{
   1905   1.1  christos 	  f = m68hc11_new_insn (2);
   1906   1.1  christos 	  number_to_chars_bigendian (f, code, 1);
   1907   1.1  christos 	  number_to_chars_bigendian (f + 1, n & 0x0FF, 1);
   1908   1.1  christos 	}
   1909   1.1  christos     }
   1910   1.1  christos   else if (opcode->format & M6812_OP_JUMP_REL16)
   1911   1.1  christos     {
   1912   1.1  christos       fix_new (frag_now, frag_now_fix (), 0,
   1913   1.1  christos                &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
   1914   1.1  christos 
   1915   1.1  christos       f = m68hc11_new_insn (2);
   1916   1.1  christos       number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1);
   1917   1.1  christos       number_to_chars_bigendian (f + 1, code, 1);
   1918   1.1  christos       fixup16 (&operands[0].exp, M6812_OP_JUMP_REL16, M6812_OP_JUMP_REL16);
   1919   1.1  christos     }
   1920   1.1  christos   else
   1921   1.1  christos     {
   1922   1.1  christos       char *op;
   1923   1.1  christos 
   1924   1.1  christos       fix_new (frag_now, frag_now_fix (), 0,
   1925   1.1  christos                &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
   1926   1.1  christos 
   1927   1.1  christos       /* Branch offset must fit in 8-bits, don't do some relax.  */
   1928   1.1  christos       if (jmp_mode == 0 && flag_fixed_branches)
   1929   1.1  christos 	{
   1930   1.1  christos 	  op = m68hc11_new_insn (1);
   1931   1.1  christos 	  number_to_chars_bigendian (op, code, 1);
   1932   1.1  christos 	  fixup8 (&operands[0].exp, M6811_OP_JUMP_REL, M6811_OP_JUMP_REL);
   1933   1.1  christos 	}
   1934   1.1  christos 
   1935   1.1  christos       /* bra/bsr made be changed into jmp/jsr.  */
   1936   1.1  christos       else if (code == M6811_BSR || code == M6811_BRA || code == M6812_BSR)
   1937  1.10  christos 	{
   1938  1.10  christos           /* Allocate worst case storage.  */
   1939   1.1  christos 	  op = m68hc11_new_insn (3);
   1940   1.1  christos 	  number_to_chars_bigendian (op, code, 1);
   1941   1.1  christos 	  number_to_chars_bigendian (op + 1, 0, 1);
   1942   1.1  christos 	  frag_variant (rs_machine_dependent, 1, 1,
   1943   1.1  christos 			ENCODE_RELAX (STATE_PC_RELATIVE, STATE_UNDF),
   1944   1.1  christos 			operands[0].exp.X_add_symbol, n, op);
   1945   1.1  christos 	}
   1946   1.1  christos       else if (current_architecture & cpu6812)
   1947  1.10  christos 	{
   1948   1.1  christos 	  op = m68hc11_new_insn (2);
   1949   1.1  christos 	  number_to_chars_bigendian (op, code, 1);
   1950   1.1  christos 	  number_to_chars_bigendian (op + 1, 0, 1);
   1951   1.1  christos 	  frag_var (rs_machine_dependent, 2, 2,
   1952   1.1  christos 		    ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_UNDF),
   1953   1.1  christos 		    operands[0].exp.X_add_symbol, n, op);
   1954   1.1  christos 	}
   1955   1.1  christos       else
   1956  1.10  christos 	{
   1957   1.1  christos 	  op = m68hc11_new_insn (2);
   1958   1.1  christos 	  number_to_chars_bigendian (op, code, 1);
   1959   1.1  christos 	  number_to_chars_bigendian (op + 1, 0, 1);
   1960   1.1  christos 	  frag_var (rs_machine_dependent, 3, 3,
   1961   1.1  christos 		    ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_UNDF),
   1962   1.1  christos 		    operands[0].exp.X_add_symbol, n, op);
   1963   1.1  christos 	}
   1964   1.1  christos     }
   1965   1.1  christos }
   1966   1.1  christos 
   1967   1.1  christos /* Builds a dbne/dbeq/tbne/tbeq instruction.  */
   1968   1.1  christos static void
   1969   1.1  christos build_dbranch_insn (struct m68hc11_opcode *opcode, operand operands[],
   1970   1.1  christos                     int nb_operands, int jmp_mode)
   1971   1.1  christos {
   1972   1.1  christos   unsigned char code;
   1973   1.1  christos   char *f;
   1974   1.1  christos   unsigned long n;
   1975   1.1  christos 
   1976   1.1  christos   /* The relative branch conversion is not supported for
   1977   1.1  christos      brclr and brset.  */
   1978   1.1  christos   gas_assert ((opcode->format & M6811_OP_BITMASK) == 0);
   1979   1.1  christos   gas_assert (nb_operands == 2);
   1980   1.1  christos   gas_assert (operands[0].reg1 != REG_NONE);
   1981   1.1  christos 
   1982   1.1  christos   code = opcode->opcode & 0x0FF;
   1983   1.1  christos 
   1984   1.1  christos   f = m68hc11_new_insn (1);
   1985   1.1  christos   number_to_chars_bigendian (f, code, 1);
   1986   1.1  christos 
   1987   1.1  christos   n = operands[1].exp.X_add_number;
   1988   1.1  christos   code = operands[0].reg1;
   1989   1.1  christos 
   1990   1.1  christos   if (operands[0].reg1 == REG_NONE || operands[0].reg1 == REG_CCR
   1991   1.1  christos       || operands[0].reg1 == REG_PC)
   1992   1.1  christos     as_bad (_("Invalid register for dbcc/tbcc instruction."));
   1993   1.1  christos 
   1994   1.1  christos   if (opcode->format & M6812_OP_IBCC_MARKER)
   1995   1.1  christos     code |= 0x80;
   1996   1.1  christos   else if (opcode->format & M6812_OP_TBCC_MARKER)
   1997   1.1  christos     code |= 0x40;
   1998   1.1  christos 
   1999   1.1  christos   if (!(opcode->format & M6812_OP_EQ_MARKER))
   2000   1.1  christos     code |= 0x20;
   2001   1.1  christos 
   2002   1.1  christos   /* Turn into a long branch:
   2003   1.1  christos      - when force long branch option (and not for jbcc pseudos),
   2004   1.1  christos      - when jdbcc and the constant is out of -256..255 range,
   2005   1.1  christos      - when branch optimization is allowed and branch out of range.  */
   2006   1.1  christos   if ((jmp_mode == 0 && flag_force_long_jumps)
   2007   1.1  christos       || (operands[1].exp.X_op == O_constant
   2008   1.1  christos 	  && (!check_range (n, M6812_OP_IBCC_MARKER) &&
   2009   1.1  christos 	      (jmp_mode == 1 || flag_fixed_branches == 0))))
   2010   1.1  christos     {
   2011   1.1  christos       f = frag_more (2);
   2012   1.1  christos       code ^= 0x20;
   2013   1.1  christos       number_to_chars_bigendian (f, code, 1);
   2014   1.1  christos       number_to_chars_bigendian (f + 1, M6812_JMP, 1);
   2015   1.1  christos       fixup16 (&operands[0].exp, M6811_OP_IND16, M6811_OP_IND16);
   2016   1.1  christos       return;
   2017   1.1  christos     }
   2018   1.1  christos 
   2019   1.1  christos   /* Branch with a constant that must fit in 9-bits.  */
   2020   1.1  christos   if (operands[1].exp.X_op == O_constant)
   2021   1.1  christos     {
   2022   1.1  christos       if (!check_range (n, M6812_OP_IBCC_MARKER))
   2023   1.1  christos 	{
   2024   1.1  christos 	  as_bad (_("Operand out of range for a relative branch: `%ld'"),
   2025   1.1  christos                   n);
   2026   1.1  christos 	}
   2027   1.1  christos       else
   2028   1.1  christos 	{
   2029   1.1  christos 	  if ((long) n < 0)
   2030   1.1  christos 	    code |= 0x10;
   2031   1.1  christos 
   2032   1.1  christos 	  f = frag_more (2);
   2033   1.1  christos 	  number_to_chars_bigendian (f, code, 1);
   2034   1.1  christos 	  number_to_chars_bigendian (f + 1, n & 0x0FF, 1);
   2035   1.1  christos 	}
   2036   1.1  christos     }
   2037   1.1  christos   else
   2038   1.1  christos     {
   2039   1.1  christos       /* Branch offset must fit in 8-bits, don't do some relax.  */
   2040   1.1  christos       if (jmp_mode == 0 && flag_fixed_branches)
   2041   1.1  christos 	{
   2042   1.1  christos 	  fixup8 (&operands[0].exp, M6811_OP_JUMP_REL, M6811_OP_JUMP_REL);
   2043   1.1  christos 	}
   2044   1.1  christos 
   2045   1.1  christos       else
   2046  1.10  christos 	{
   2047   1.1  christos 	  f = frag_more (2);
   2048   1.1  christos 	  number_to_chars_bigendian (f, code, 1);
   2049   1.1  christos 	  number_to_chars_bigendian (f + 1, 0, 1);
   2050   1.1  christos 	  frag_var (rs_machine_dependent, 3, 3,
   2051   1.1  christos 		    ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_UNDF),
   2052   1.1  christos 		    operands[1].exp.X_add_symbol, n, f);
   2053   1.1  christos 	}
   2054   1.1  christos     }
   2055   1.1  christos }
   2056   1.1  christos 
   2057   1.1  christos #define OP_EXTENDED (M6811_OP_PAGE2 | M6811_OP_PAGE3 | M6811_OP_PAGE4)
   2058   1.1  christos 
   2059   1.1  christos /* Assemble the post index byte for 68HC12 extended addressing modes.  */
   2060   1.1  christos 
   2061   1.1  christos static int
   2062   1.1  christos build_indexed_byte (operand *op, int format ATTRIBUTE_UNUSED, int move_insn)
   2063   1.1  christos {
   2064   1.1  christos   unsigned char byte = 0;
   2065   1.1  christos   char *f;
   2066   1.1  christos   int mode;
   2067   1.1  christos   long val;
   2068   1.1  christos 
   2069   1.1  christos   val = op->exp.X_add_number;
   2070   1.1  christos   mode = op->mode;
   2071   1.1  christos   if (mode & M6812_AUTO_INC_DEC)
   2072   1.1  christos     {
   2073   1.1  christos       byte = 0x20;
   2074   1.1  christos       if (mode & (M6812_POST_INC | M6812_POST_DEC))
   2075   1.1  christos 	byte |= 0x10;
   2076   1.1  christos 
   2077   1.1  christos       if (op->exp.X_op == O_constant)
   2078   1.1  christos 	{
   2079   1.1  christos 	  if (!check_range (val, mode))
   2080   1.1  christos 	    as_bad (_("Increment/decrement value is out of range: `%ld'."),
   2081   1.1  christos 		    val);
   2082   1.1  christos 
   2083   1.1  christos 	  if (mode & (M6812_POST_INC | M6812_PRE_INC))
   2084   1.1  christos 	    byte |= (val - 1) & 0x07;
   2085   1.1  christos 	  else
   2086   1.1  christos 	    byte |= (8 - ((val) & 7)) | 0x8;
   2087   1.1  christos 	}
   2088   1.1  christos 
   2089   1.1  christos       switch (op->reg1)
   2090   1.1  christos 	{
   2091   1.1  christos 	case REG_NONE:
   2092   1.1  christos 	  as_fatal (_("Expecting a register."));
   2093   1.1  christos 
   2094   1.1  christos 	case REG_X:
   2095   1.1  christos 	  byte |= 0;
   2096   1.1  christos 	  break;
   2097   1.1  christos 
   2098   1.1  christos 	case REG_Y:
   2099   1.1  christos 	  byte |= 0x40;
   2100   1.1  christos 	  break;
   2101   1.1  christos 
   2102   1.1  christos 	case REG_SP:
   2103   1.1  christos 	  byte |= 0x80;
   2104   1.1  christos 	  break;
   2105   1.1  christos 
   2106   1.1  christos 	default:
   2107   1.1  christos 	  as_bad (_("Invalid register for post/pre increment."));
   2108   1.1  christos 	  break;
   2109   1.1  christos 	}
   2110   1.1  christos 
   2111   1.1  christos       f = frag_more (1);
   2112   1.1  christos       number_to_chars_bigendian (f, byte, 1);
   2113   1.1  christos       return 1;
   2114   1.1  christos     }
   2115   1.1  christos 
   2116   1.1  christos   if (mode & (M6812_OP_IDX | M6812_OP_D_IDX_2))
   2117   1.1  christos     {
   2118   1.1  christos       switch (op->reg1)
   2119   1.1  christos 	{
   2120   1.1  christos 	case REG_X:
   2121   1.1  christos 	  byte = 0;
   2122   1.1  christos 	  break;
   2123   1.1  christos 
   2124   1.1  christos 	case REG_Y:
   2125   1.1  christos 	  byte = 1;
   2126   1.1  christos 	  break;
   2127   1.1  christos 
   2128   1.1  christos 	case REG_SP:
   2129   1.1  christos 	  byte = 2;
   2130   1.1  christos 	  break;
   2131   1.1  christos 
   2132   1.1  christos 	case REG_PC:
   2133   1.1  christos 	  byte = 3;
   2134   1.1  christos 	  break;
   2135   1.1  christos 
   2136   1.1  christos 	default:
   2137   1.1  christos 	  as_bad (_("Invalid register."));
   2138   1.1  christos 	  break;
   2139   1.1  christos 	}
   2140   1.3  christos 
   2141   1.3  christos       if (op->exp.X_op == O_constant)
   2142   1.1  christos 	{
   2143   1.1  christos 	  if (!check_range (val, M6812_OP_IDX))
   2144   1.1  christos 	    as_bad (_("Offset out of 16-bit range: %ld."), val);
   2145   1.1  christos 
   2146   1.1  christos 	  if (move_insn && !(val >= -16 && val <= 15)
   2147   1.1  christos 	      && ((!(mode & M6812_OP_IDX) && !(mode & M6812_OP_D_IDX_2))
   2148   1.1  christos 		  || !(current_architecture & cpu9s12x)))
   2149   1.1  christos 	    {
   2150   1.1  christos 	      as_bad (_("Offset out of 5-bit range for movw/movb insn: %ld."),
   2151   1.1  christos 		      val);
   2152   1.1  christos 	      return -1;
   2153   1.1  christos 	    }
   2154   1.1  christos 
   2155   1.1  christos 	  if (val >= -16 && val <= 15 && !(mode & M6812_OP_D_IDX_2))
   2156   1.1  christos 	    {
   2157   1.1  christos 	      byte = byte << 6;
   2158   1.1  christos 	      byte |= val & 0x1f;
   2159   1.1  christos 	      f = frag_more (1);
   2160   1.1  christos 	      number_to_chars_bigendian (f, byte, 1);
   2161   1.1  christos 	      return 1;
   2162   1.1  christos 	    }
   2163   1.1  christos 	  else if (val >= -256 && val <= 255 && !(mode & M6812_OP_D_IDX_2))
   2164   1.1  christos 	    {
   2165   1.1  christos 	      byte = byte << 3;
   2166   1.1  christos 	      byte |= 0xe0;
   2167   1.1  christos 	      if (val < 0)
   2168   1.1  christos 		byte |= 0x1;
   2169   1.1  christos 	      f = frag_more (2);
   2170   1.1  christos 	      number_to_chars_bigendian (f, byte, 1);
   2171   1.1  christos 	      number_to_chars_bigendian (f + 1, val & 0x0FF, 1);
   2172   1.1  christos 	      return 2;
   2173   1.1  christos 	    }
   2174   1.1  christos 	  else
   2175   1.1  christos 	    {
   2176   1.1  christos 	      byte = byte << 3;
   2177   1.1  christos 	      if (mode & M6812_OP_D_IDX_2)
   2178   1.1  christos 		byte |= 0xe3;
   2179   1.1  christos 	      else
   2180   1.1  christos 		byte |= 0xe2;
   2181   1.1  christos 
   2182   1.1  christos 	      f = frag_more (3);
   2183   1.1  christos 	      number_to_chars_bigendian (f, byte, 1);
   2184   1.1  christos 	      number_to_chars_bigendian (f + 1, val & 0x0FFFF, 2);
   2185   1.1  christos 	      return 3;
   2186   1.1  christos 	    }
   2187   1.1  christos 	}
   2188   1.1  christos 
   2189   1.1  christos       if (mode & M6812_OP_D_IDX_2)
   2190   1.1  christos         {
   2191   1.1  christos           byte = (byte << 3) | 0xe3;
   2192   1.1  christos           f = frag_more (1);
   2193   1.1  christos           number_to_chars_bigendian (f, byte, 1);
   2194   1.1  christos 
   2195   1.1  christos           fixup16 (&op->exp, 0, 0);
   2196   1.1  christos         }
   2197   1.1  christos       else if (op->reg1 != REG_PC)
   2198   1.1  christos 	{
   2199   1.1  christos           symbolS *sym;
   2200   1.1  christos           offsetT off;
   2201   1.1  christos 
   2202   1.1  christos 	  f = frag_more (1);
   2203   1.1  christos 	  number_to_chars_bigendian (f, byte, 1);
   2204   1.1  christos           sym = op->exp.X_add_symbol;
   2205   1.1  christos           off = op->exp.X_add_number;
   2206   1.1  christos           if (op->exp.X_op != O_symbol)
   2207   1.1  christos             {
   2208   1.1  christos               sym = make_expr_symbol (&op->exp);
   2209   1.1  christos               off = 0;
   2210   1.1  christos             }
   2211   1.1  christos 
   2212   1.1  christos 	  /* movb/movw cannot be relaxed.  */
   2213   1.1  christos 	  if (move_insn)
   2214   1.1  christos 	    {
   2215   1.1  christos 	      if ((mode & M6812_OP_IDX) && (current_architecture & cpu9s12x))
   2216   1.1  christos 		{
   2217   1.1  christos 		  /* Must treat as a 16bit relocate as size of final result is unknown.  */
   2218   1.1  christos 
   2219   1.1  christos 		  byte <<= 3;
   2220   1.1  christos 		  byte |= 0xe2;
   2221   1.1  christos 		  number_to_chars_bigendian (f, byte, 1);
   2222   1.1  christos 		  f = frag_more (2);
   2223   1.1  christos 		  fix_new (frag_now, f - frag_now->fr_literal, 2,
   2224   1.1  christos 			   sym, off, 0, BFD_RELOC_M68HC12_16B);
   2225   1.1  christos 		  return 1;
   2226   1.1  christos 		}
   2227   1.1  christos 	      else
   2228   1.1  christos 		{
   2229   1.1  christos 		  /* Non-S12X will fail at relocate stage if offset out of range.  */
   2230   1.1  christos 		  byte <<= 6;
   2231   1.1  christos 		  number_to_chars_bigendian (f, byte, 1);
   2232   1.1  christos 		  fix_new (frag_now, f - frag_now->fr_literal, 1,
   2233   1.1  christos 			   sym, off, 0, BFD_RELOC_M68HC12_5B);
   2234   1.1  christos 		  return 1;
   2235   1.1  christos 		}
   2236   1.1  christos 	    }
   2237   1.1  christos 	  else
   2238   1.1  christos 	    {
   2239   1.1  christos 	      number_to_chars_bigendian (f, byte, 1);
   2240   1.1  christos 	      frag_var (rs_machine_dependent, 2, 2,
   2241   1.1  christos 			ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_UNDF),
   2242   1.1  christos 			sym, off, f);
   2243   1.1  christos 	    }
   2244   1.1  christos 	}
   2245   1.1  christos       else
   2246   1.1  christos 	{
   2247   1.1  christos 	  f = frag_more (1);
   2248   1.1  christos 
   2249   1.1  christos 	  /* movb/movw cannot be relaxed.  */
   2250   1.1  christos 	  if (move_insn)
   2251   1.1  christos 	    {
   2252   1.1  christos 	      byte <<= 6;
   2253   1.1  christos 	      number_to_chars_bigendian (f, byte, 1);
   2254   1.1  christos 	      fix_new (frag_now, f - frag_now->fr_literal, 1,
   2255   1.1  christos 		       op->exp.X_add_symbol, op->exp.X_add_number, 0, BFD_RELOC_M68HC12_5B);
   2256   1.1  christos 	      return 1;
   2257   1.1  christos 	    }
   2258   1.1  christos 	  else
   2259   1.1  christos 	    {
   2260   1.1  christos 	      number_to_chars_bigendian (f, byte, 1);
   2261   1.1  christos 	      frag_var (rs_machine_dependent, 2, 2,
   2262   1.1  christos 			ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_UNDF),
   2263   1.1  christos 			op->exp.X_add_symbol,
   2264   1.1  christos 			op->exp.X_add_number, f);
   2265   1.1  christos 	    }
   2266   1.1  christos 	}
   2267   1.1  christos       return 3;
   2268   1.1  christos     }
   2269   1.1  christos 
   2270   1.1  christos   if (mode & (M6812_OP_REG | M6812_OP_D_IDX))
   2271   1.1  christos     {
   2272   1.1  christos       if (mode & M6812_OP_D_IDX)
   2273   1.1  christos 	{
   2274   1.1  christos 	  if (op->reg1 != REG_D)
   2275   1.1  christos 	    as_bad (_("Expecting register D for indexed indirect mode."));
   2276   1.1  christos 	  if ((move_insn) && (!(current_architecture & cpu9s12x)))
   2277   1.1  christos 	    as_bad (_("Indexed indirect mode is not allowed for movb/movw."));
   2278   1.1  christos 
   2279   1.1  christos 	  byte = 0xE7;
   2280   1.1  christos 	}
   2281   1.1  christos       else
   2282   1.1  christos 	{
   2283   1.1  christos 	  switch (op->reg1)
   2284   1.1  christos 	    {
   2285   1.1  christos 	    case REG_A:
   2286   1.1  christos 	      byte = 0xE4;
   2287   1.1  christos 	      break;
   2288   1.1  christos 
   2289   1.6  christos 	    case REG_B:
   2290   1.1  christos 	      byte = 0xE5;
   2291   1.1  christos 	      break;
   2292   1.1  christos 
   2293   1.1  christos 	    default:
   2294   1.1  christos 	      as_bad (_("Invalid accumulator register."));
   2295   1.1  christos 	      /* Fall through.  */
   2296   1.1  christos 
   2297   1.1  christos 	    case REG_D:
   2298   1.1  christos 	      byte = 0xE6;
   2299   1.1  christos 	      break;
   2300   1.1  christos 	    }
   2301   1.1  christos 	}
   2302   1.1  christos       switch (op->reg2)
   2303   1.1  christos 	{
   2304   1.1  christos 	case REG_X:
   2305   1.1  christos 	  break;
   2306   1.1  christos 
   2307   1.1  christos 	case REG_Y:
   2308   1.1  christos 	  byte |= (1 << 3);
   2309   1.1  christos 	  break;
   2310   1.1  christos 
   2311   1.1  christos 	case REG_SP:
   2312   1.1  christos 	  byte |= (2 << 3);
   2313   1.1  christos 	  break;
   2314   1.1  christos 
   2315   1.1  christos 	case REG_PC:
   2316   1.1  christos 	  byte |= (3 << 3);
   2317   1.1  christos 	  break;
   2318   1.1  christos 
   2319   1.1  christos 	default:
   2320   1.1  christos 	  as_bad (_("Invalid indexed register."));
   2321   1.1  christos 	  break;
   2322   1.1  christos 	}
   2323   1.1  christos       f = frag_more (1);
   2324   1.1  christos       number_to_chars_bigendian (f, byte, 1);
   2325   1.1  christos       return 1;
   2326   1.1  christos     }
   2327   1.1  christos 
   2328   1.1  christos   fprintf (stderr, "mode = 0x%x\nop->reg1 = 0x%x\nop->reg2 = 0x%x\n",
   2329   1.1  christos 	   mode, op->reg1, op->reg2);
   2330   1.1  christos   as_fatal (_("Addressing mode not implemented yet."));
   2331   1.1  christos   return 0;
   2332   1.1  christos }
   2333   1.1  christos 
   2334   1.1  christos /* Assemble the 68HC12 register mode byte.  */
   2335   1.1  christos static int
   2336   1.1  christos build_reg_mode (operand *op, int format)
   2337   1.1  christos {
   2338   1.1  christos   unsigned char byte;
   2339   1.1  christos   char *f;
   2340   1.1  christos 
   2341   1.1  christos   if ((format & M6812_OP_SEX_MARKER)
   2342   1.1  christos       && (op->reg1 != REG_A) && (op->reg1 != REG_B) && (op->reg1 != REG_CCR)
   2343   1.1  christos 	  && (!(current_architecture & cpu9s12x)))
   2344   1.1  christos     as_bad (_("Invalid source register for this instruction, use 'tfr'."));
   2345   1.1  christos   else if (op->reg1 == REG_NONE || op->reg1 == REG_PC)
   2346   1.1  christos     as_bad (_("Invalid source register."));
   2347   1.1  christos 
   2348   1.1  christos   if (format & M6812_OP_SEX_MARKER
   2349   1.1  christos       && op->reg2 != REG_D
   2350   1.1  christos       && op->reg2 != REG_X && op->reg2 != REG_Y && op->reg2 != REG_SP)
   2351   1.1  christos     as_bad (_("Invalid destination register for this instruction, use 'tfr'."));
   2352   1.1  christos   else if (op->reg2 == REG_NONE || op->reg2 == REG_PC)
   2353   1.1  christos     as_bad (_("Invalid destination register."));
   2354   1.1  christos 
   2355   1.1  christos   byte = (op->reg1 << 4) | (op->reg2);
   2356   1.1  christos   if (format & M6812_OP_EXG_MARKER)
   2357   1.1  christos     byte |= 0x80;
   2358   1.1  christos 
   2359   1.1  christos   if ((format & M6812_OP_SEX_MARKER)
   2360   1.1  christos       && (op->reg1 == REG_D) && (current_architecture & cpu9s12x))
   2361   1.1  christos 	byte |= 0x08;
   2362   1.1  christos 
   2363   1.1  christos   f = frag_more (1);
   2364   1.1  christos   number_to_chars_bigendian (f, byte, 1);
   2365   1.1  christos   return 1;
   2366   1.1  christos }
   2367   1.1  christos 
   2368   1.1  christos /* build_insn_xg takes a pointer to the opcode entry in the opcode table,
   2369   1.1  christos    the array of operand expressions and builds the corresponding instruction.  */
   2370   1.1  christos 
   2371   1.1  christos static void
   2372   1.1  christos build_insn_xg (struct m68hc11_opcode *opcode,
   2373   1.1  christos 	       operand operands[],
   2374   1.1  christos 	       int nb_operands ATTRIBUTE_UNUSED)
   2375   1.1  christos {
   2376   1.1  christos   char *f;
   2377   1.1  christos   long format;
   2378   1.1  christos 
   2379   1.1  christos   /* Put the page code instruction if there is one.  */
   2380   1.1  christos   format = opcode->format;
   2381   1.1  christos 
   2382   1.1  christos   if (!(operands[0].mode & (M6811_OP_LOW_ADDR | M6811_OP_HIGH_ADDR)))
   2383   1.1  christos     /* Need to retain those two modes, but clear for others. */
   2384   1.1  christos     operands[0].mode = 0;
   2385   1.1  christos 
   2386   1.1  christos   if (format & M68XG_OP_R_IMM8)
   2387   1.1  christos     {
   2388   1.1  christos       /* These opcodes are byte followed by imm8.  */
   2389   1.1  christos       f = m68hc11_new_insn (1);
   2390   1.1  christos       number_to_chars_bigendian (f, opcode->opcode >> 8, 1);
   2391   1.1  christos       fixup8_xg (&operands[0].exp, format, operands[0].mode);
   2392   1.1  christos     }
   2393   1.1  christos   else if (format & M68XG_OP_R_IMM16)
   2394   1.1  christos     {
   2395   1.1  christos       fixS *fixp;
   2396   1.1  christos       /* These opcodes expand into two imm8 instructions.
   2397   1.1  christos          Emit as low:high as per the Freescale datasheet.
   2398   1.1  christos          The linker requires them to be adjacent to handle the upper byte.  */
   2399   1.1  christos 
   2400   1.8  christos       /* Build low byte.  */
   2401   1.1  christos       f = m68hc11_new_insn (1);
   2402   1.1  christos       number_to_chars_bigendian (f, opcode->opcode >> 8, 1);
   2403   1.1  christos       operands[0].mode = M6811_OP_LOW_ADDR;
   2404   1.1  christos       f = frag_more (1);
   2405   1.1  christos       fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
   2406   1.1  christos                           &operands[0].exp, false, BFD_RELOC_M68HC12_LO8XG);
   2407   1.1  christos       fixp->fx_no_overflow = 1;
   2408   1.1  christos       number_to_chars_bigendian (f, 0, 1);
   2409   1.1  christos 
   2410   1.8  christos       /* Build high byte.  */
   2411   1.1  christos       f = m68hc11_new_insn (1);
   2412   1.1  christos       number_to_chars_bigendian (f, (opcode->opcode >> 8) | 0x08, 1);
   2413   1.1  christos       operands[0].mode = M6811_OP_HIGH_ADDR;
   2414   1.1  christos       f = frag_more (1);
   2415   1.1  christos       fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
   2416   1.1  christos                           &operands[0].exp, false, BFD_RELOC_M68HC12_HI8XG);
   2417   1.1  christos       fixp->fx_no_overflow = 1;
   2418   1.1  christos       number_to_chars_bigendian (f, 0, 1);
   2419   1.1  christos 
   2420   1.3  christos     }
   2421   1.1  christos   else if (format & M68XG_OP_REL9)
   2422   1.1  christos     {
   2423   1.1  christos       f = m68hc11_new_insn (1);
   2424   1.1  christos       number_to_chars_bigendian (f, opcode->opcode >> 8, 1); /* High byte.  */
   2425   1.1  christos       fixup8_xg (&operands[0].exp, format, M68XG_OP_REL9);
   2426   1.1  christos     }
   2427   1.1  christos   else if (format & M68XG_OP_REL10)
   2428   1.1  christos     {
   2429   1.1  christos       f = m68hc11_new_insn (1);
   2430   1.1  christos       number_to_chars_bigendian (f, opcode->opcode >> 8, 1); /* High byte.  */
   2431   1.1  christos       fixup8_xg (&operands[0].exp, format, M68XG_OP_REL10);
   2432   1.1  christos     }
   2433   1.1  christos   else
   2434   1.1  christos     {
   2435   1.1  christos       f = m68hc11_new_insn (2);
   2436   1.1  christos       number_to_chars_bigendian (f, opcode->opcode, 2);
   2437   1.1  christos     }
   2438   1.1  christos   return;
   2439   1.1  christos }
   2440   1.1  christos 
   2441   1.1  christos /* build_insn takes a pointer to the opcode entry in the opcode table,
   2442   1.1  christos    the array of operand expressions and builds the corresponding instruction.
   2443   1.1  christos    This operation only deals with non relative jumps insn (need special
   2444   1.1  christos    handling).  */
   2445   1.1  christos 
   2446   1.1  christos static void
   2447   1.1  christos build_insn (struct m68hc11_opcode *opcode,
   2448   1.1  christos 	    operand operands[],
   2449   1.1  christos             int nb_operands ATTRIBUTE_UNUSED)
   2450   1.1  christos {
   2451   1.1  christos   int i;
   2452   1.1  christos   char *f;
   2453   1.1  christos   long format;
   2454   1.1  christos   int move_insn = 0;
   2455   1.1  christos 
   2456   1.1  christos   /* Put the page code instruction if there is one.  */
   2457   1.1  christos   format = opcode->format;
   2458   1.1  christos 
   2459   1.1  christos   if (format & M6811_OP_BRANCH)
   2460   1.1  christos     fix_new (frag_now, frag_now_fix (), 0,
   2461   1.1  christos              &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
   2462   1.1  christos 
   2463   1.1  christos   if (format & OP_EXTENDED)
   2464   1.1  christos     {
   2465   1.1  christos       int page_code;
   2466   1.1  christos 
   2467   1.1  christos       f = m68hc11_new_insn (2);
   2468   1.1  christos       if (format & M6811_OP_PAGE2)
   2469   1.1  christos 	page_code = M6811_OPCODE_PAGE2;
   2470   1.1  christos       else if (format & M6811_OP_PAGE3)
   2471   1.1  christos 	page_code = M6811_OPCODE_PAGE3;
   2472   1.1  christos       else
   2473   1.1  christos 	page_code = M6811_OPCODE_PAGE4;
   2474   1.1  christos 
   2475   1.1  christos       number_to_chars_bigendian (f, page_code, 1);
   2476   1.1  christos       f++;
   2477   1.1  christos     }
   2478   1.1  christos   else
   2479   1.1  christos     f = m68hc11_new_insn (1);
   2480   1.1  christos 
   2481   1.1  christos   number_to_chars_bigendian (f, opcode->opcode, 1);
   2482   1.1  christos 
   2483   1.1  christos   i = 0;
   2484   1.1  christos 
   2485   1.1  christos   /* The 68HC12 movb and movw instructions are special.  We have to handle
   2486   1.1  christos      them in a special way.  */
   2487   1.1  christos   if (format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2))
   2488   1.1  christos     {
   2489   1.1  christos       move_insn = 1;
   2490   1.1  christos       if (format & M6812_OP_IDX)
   2491   1.1  christos 	{
   2492   1.1  christos 	  build_indexed_byte (&operands[0], format, 1);
   2493   1.1  christos 	  i = 1;
   2494   1.1  christos 	  format &= ~M6812_OP_IDX;
   2495   1.1  christos 	}
   2496   1.1  christos       if (format & M6812_OP_IDX_P2)
   2497   1.1  christos 	{
   2498   1.1  christos 	  build_indexed_byte (&operands[1], format, 1);
   2499   1.1  christos 	  i = 0;
   2500   1.1  christos 	  format &= ~M6812_OP_IDX_P2;
   2501   1.1  christos 	}
   2502   1.1  christos     }
   2503   1.1  christos 
   2504   1.1  christos   if (format & (M6811_OP_DIRECT | M6811_OP_IMM8))
   2505   1.1  christos     {
   2506   1.1  christos       fixup8 (&operands[i].exp,
   2507   1.1  christos 	      format & (M6811_OP_DIRECT | M6811_OP_IMM8 | M6812_OP_TRAP_ID),
   2508   1.1  christos 	      operands[i].mode);
   2509   1.1  christos       i++;
   2510   1.1  christos     }
   2511   1.1  christos   else if (IS_CALL_SYMBOL (format) && nb_operands == 1)
   2512   1.1  christos     {
   2513   1.1  christos       format &= ~M6812_OP_PAGE;
   2514   1.1  christos       fixup24 (&operands[i].exp, format & M6811_OP_IND16,
   2515   1.1  christos 	       operands[i].mode);
   2516   1.1  christos       i++;
   2517   1.1  christos     }
   2518   1.1  christos   else if (format & (M6811_OP_IMM16 | M6811_OP_IND16))
   2519   1.1  christos     {
   2520   1.1  christos       fixup16 (&operands[i].exp,
   2521   1.1  christos                format & (M6811_OP_IMM16 | M6811_OP_IND16 | M6812_OP_PAGE),
   2522   1.1  christos 	       operands[i].mode);
   2523   1.1  christos       i++;
   2524   1.1  christos     }
   2525   1.1  christos   else if (format & (M6811_OP_IX | M6811_OP_IY))
   2526   1.1  christos     {
   2527   1.1  christos       if ((format & M6811_OP_IX) && (operands[0].reg1 != REG_X))
   2528   1.1  christos 	as_bad (_("Invalid indexed register, expecting register X."));
   2529   1.1  christos       if ((format & M6811_OP_IY) && (operands[0].reg1 != REG_Y))
   2530   1.1  christos 	as_bad (_("Invalid indexed register, expecting register Y."));
   2531   1.1  christos 
   2532   1.1  christos       fixup8 (&operands[0].exp, M6811_OP_IX, operands[0].mode);
   2533   1.1  christos       i = 1;
   2534   1.1  christos     }
   2535   1.1  christos   else if (format &
   2536   1.1  christos 	   (M6812_OP_IDX | M6812_OP_IDX_2 | M6812_OP_IDX_1
   2537   1.1  christos             | M6812_OP_D_IDX | M6812_OP_D_IDX_2))
   2538   1.1  christos     {
   2539   1.1  christos       build_indexed_byte (&operands[i], format, move_insn);
   2540   1.1  christos       i++;
   2541   1.1  christos     }
   2542   1.1  christos   else if (format & M6812_OP_REG && current_architecture & cpu6812)
   2543   1.1  christos     {
   2544   1.1  christos       build_reg_mode (&operands[i], format);
   2545   1.1  christos       i++;
   2546   1.1  christos     }
   2547   1.1  christos   if (format & M6811_OP_BITMASK)
   2548   1.1  christos     {
   2549   1.1  christos       fixup8 (&operands[i].exp, M6811_OP_BITMASK, operands[i].mode);
   2550   1.1  christos       i++;
   2551   1.1  christos     }
   2552   1.1  christos   if (format & M6811_OP_JUMP_REL)
   2553   1.1  christos     {
   2554   1.1  christos       fixup8 (&operands[i].exp, M6811_OP_JUMP_REL, operands[i].mode);
   2555   1.1  christos     }
   2556   1.1  christos   else if (format & M6812_OP_IND16_P2)
   2557   1.1  christos     {
   2558   1.1  christos       fixup16 (&operands[1].exp, M6811_OP_IND16, operands[1].mode);
   2559   1.1  christos     }
   2560   1.1  christos   if (format & M6812_OP_PAGE)
   2561   1.1  christos     {
   2562   1.1  christos       fixup8 (&operands[i].exp, M6812_OP_PAGE, operands[i].mode);
   2563   1.1  christos     }
   2564   1.1  christos }
   2565   1.1  christos 
   2566   1.1  christos /* Opcode identification and operand analysis.  */
   2568   1.1  christos 
   2569   1.1  christos /* find() gets a pointer to an entry in the opcode table.  It must look at all
   2570   1.1  christos    opcodes with the same name and use the operands to choose the correct
   2571   1.1  christos    opcode.  Returns the opcode pointer if there was a match and 0 if none.  */
   2572   1.1  christos static struct m68hc11_opcode *
   2573   1.1  christos find (struct m68hc11_opcode_def *opc, operand operands[], int nb_operands)
   2574   1.1  christos {
   2575   1.1  christos   int i, match, pos;
   2576   1.1  christos   struct m68hc11_opcode *opcode;
   2577   1.1  christos   struct m68hc11_opcode *op_indirect;
   2578   1.1  christos 
   2579   1.1  christos   op_indirect = 0;
   2580   1.1  christos   opcode = opc->opcode;
   2581   1.1  christos 
   2582   1.1  christos   /* Now search the opcode table table for one with operands
   2583   1.1  christos      that matches what we've got.  */
   2584   1.1  christos 
   2585   1.1  christos   if (current_architecture & cpuxgate)
   2586   1.1  christos     {
   2587   1.1  christos       /* Many XGATE insns are simple enough that we get an exact match.  */
   2588   1.1  christos       for (pos = match = 0; match == 0 && pos < opc->nb_modes; pos++, opcode++)
   2589   1.1  christos         if (opcode->format == operands[nb_operands-1].mode)
   2590   1.1  christos 	  return opcode;
   2591   1.1  christos 
   2592   1.1  christos       return 0;
   2593   1.1  christos     }
   2594   1.1  christos 
   2595   1.1  christos   /* Non XGATE */
   2596   1.1  christos 
   2597   1.1  christos   /* Now search the opcode table table for one with operands
   2598   1.1  christos      that matches what we've got.  We're only done if the operands matched so
   2599   1.1  christos      far AND there are no more to check.  */
   2600   1.1  christos   for (pos = match = 0; match == 0 && pos < opc->nb_modes; pos++, opcode++)
   2601   1.1  christos     {
   2602   1.1  christos       int poss_indirect = 0;
   2603   1.1  christos       long format = opcode->format;
   2604   1.1  christos       int expect;
   2605   1.1  christos 
   2606   1.1  christos       expect = 0;
   2607   1.1  christos       if (opcode->format & M6811_OP_MASK)
   2608   1.1  christos 	expect++;
   2609   1.1  christos       if (opcode->format & M6811_OP_BITMASK)
   2610   1.1  christos 	expect++;
   2611   1.1  christos       if (opcode->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
   2612   1.1  christos 	expect++;
   2613   1.1  christos       if (opcode->format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2))
   2614   1.1  christos 	expect++;
   2615   1.1  christos       if ((opcode->format & M6812_OP_PAGE)
   2616   1.1  christos           && (!IS_CALL_SYMBOL (opcode->format) || nb_operands == 2))
   2617   1.1  christos         expect++;
   2618   1.1  christos 
   2619   1.1  christos       for (i = 0; expect == nb_operands && i < nb_operands; i++)
   2620   1.1  christos 	{
   2621   1.1  christos 	  int mode = operands[i].mode;
   2622   1.1  christos 
   2623   1.1  christos 	  if (mode & M6811_OP_IMM16)
   2624   1.1  christos 	    {
   2625   1.1  christos 	      if (format &
   2626   1.1  christos 		  (M6811_OP_IMM8 | M6811_OP_IMM16 | M6811_OP_BITMASK))
   2627   1.1  christos 		continue;
   2628   1.1  christos 	      break;
   2629   1.1  christos 	    }
   2630   1.1  christos 	  if (mode == M6811_OP_DIRECT)
   2631   1.1  christos 	    {
   2632   1.1  christos 	      if (format & M6811_OP_DIRECT)
   2633   1.1  christos 		continue;
   2634   1.1  christos 
   2635   1.1  christos 	      /* If the operand is a page 0 operand, remember a
   2636   1.1  christos 	         possible <abs-16> addressing mode.  We mark
   2637   1.1  christos 	         this and continue to check other operands.  */
   2638   1.1  christos 	      if (format & M6811_OP_IND16
   2639   1.1  christos 		  && flag_strict_direct_addressing && op_indirect == 0)
   2640   1.1  christos 		{
   2641   1.1  christos 		  poss_indirect = 1;
   2642   1.1  christos 		  continue;
   2643   1.1  christos 		}
   2644   1.1  christos 	      break;
   2645   1.1  christos 	    }
   2646   1.1  christos 	  if (mode & M6811_OP_IND16)
   2647   1.1  christos 	    {
   2648   1.1  christos 	      if (i == 0 && (format & M6811_OP_IND16) != 0)
   2649   1.1  christos 		continue;
   2650   1.1  christos               if (i != 0 && (format & M6812_OP_PAGE) != 0)
   2651   1.1  christos                 continue;
   2652   1.1  christos 	      if (i != 0 && (format & M6812_OP_IND16_P2) != 0)
   2653   1.1  christos 		continue;
   2654   1.1  christos 	      if (i == 0 && (format & M6811_OP_BITMASK))
   2655   1.1  christos 		break;
   2656   1.1  christos 	    }
   2657   1.1  christos 	  if (mode & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
   2658   1.1  christos 	    {
   2659   1.1  christos 	      if (format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
   2660   1.1  christos 		continue;
   2661   1.1  christos 	    }
   2662   1.1  christos 	  if (mode & M6812_OP_REG)
   2663   1.1  christos 	    {
   2664   1.1  christos 	      if (i == 0
   2665   1.1  christos 		  && (format & M6812_OP_REG)
   2666   1.1  christos 		  && (operands[i].reg2 == REG_NONE))
   2667   1.1  christos 		continue;
   2668   1.1  christos 	      if (i == 0
   2669   1.1  christos 		  && (format & M6812_OP_REG)
   2670   1.1  christos 		  && (format & M6812_OP_REG_2)
   2671   1.1  christos 		  && (operands[i].reg2 != REG_NONE))
   2672   1.1  christos 		continue;
   2673   1.1  christos 	      if (i == 0
   2674   1.1  christos 		  && (format & M6812_OP_IDX)
   2675   1.1  christos 		  && (operands[i].reg2 != REG_NONE))
   2676   1.1  christos 		continue;
   2677   1.1  christos 	      if (i == 0
   2678   1.1  christos 		  && (format & M6812_OP_IDX)
   2679   1.1  christos 		  && (format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2)))
   2680   1.1  christos 		continue;
   2681   1.1  christos 	      if (i == 1
   2682   1.1  christos 		  && (format & M6812_OP_IDX_P2))
   2683   1.1  christos 		continue;
   2684   1.1  christos 	      break;
   2685   1.1  christos 	    }
   2686   1.1  christos 	  if (mode & M6812_OP_IDX)
   2687   1.1  christos 	    {
   2688   1.1  christos 	      if (format & M6811_OP_IX && operands[i].reg1 == REG_X)
   2689   1.1  christos 		continue;
   2690   1.1  christos 	      if (format & M6811_OP_IY && operands[i].reg1 == REG_Y)
   2691   1.1  christos 		continue;
   2692   1.1  christos 	      if (i == 0
   2693   1.1  christos 		  && format & (M6812_OP_IDX | M6812_OP_IDX_1 | M6812_OP_IDX_2)
   2694   1.1  christos 		  && (operands[i].reg1 == REG_X
   2695   1.1  christos 		      || operands[i].reg1 == REG_Y
   2696   1.1  christos 		      || operands[i].reg1 == REG_SP
   2697   1.1  christos 		      || operands[i].reg1 == REG_PC))
   2698   1.1  christos 		continue;
   2699   1.1  christos 	      if (i == 1 && (format & M6812_OP_IDX_P2))
   2700   1.1  christos 		continue;
   2701   1.1  christos 	    }
   2702   1.1  christos           if (mode & format & (M6812_OP_D_IDX | M6812_OP_D_IDX_2))
   2703   1.1  christos             {
   2704   1.1  christos               if (i == 0)
   2705   1.1  christos                 continue;
   2706   1.1  christos             }
   2707   1.1  christos 	  if (mode & M6812_AUTO_INC_DEC)
   2708   1.1  christos 	    {
   2709   1.1  christos 	      if (i == 0
   2710   1.1  christos 		  && format & (M6812_OP_IDX | M6812_OP_IDX_1 |
   2711   1.1  christos 			       M6812_OP_IDX_2))
   2712   1.1  christos 		continue;
   2713   1.1  christos 	      if (i == 1 && format & M6812_OP_IDX_P2)
   2714   1.1  christos 		continue;
   2715   1.1  christos 	    }
   2716   1.1  christos 	  break;
   2717   1.1  christos 	}
   2718   1.1  christos       match = i == nb_operands;
   2719   1.1  christos 
   2720   1.1  christos       /* Operands are ok but an operand uses page 0 addressing mode
   2721   1.1  christos          while the insn supports abs-16 mode.  Keep a reference to this
   2722   1.1  christos          insns in case there is no insn supporting page 0 addressing.  */
   2723   1.1  christos       if (match && poss_indirect)
   2724   1.1  christos 	{
   2725   1.1  christos 	  op_indirect = opcode;
   2726   1.1  christos 	  match = 0;
   2727   1.1  christos 	}
   2728   1.1  christos       if (match)
   2729   1.1  christos 	break;
   2730   1.1  christos     }
   2731   1.1  christos 
   2732   1.1  christos   /* Page 0 addressing is used but not supported by any insn.
   2733   1.1  christos      If absolute addresses are supported, we use that insn.  */
   2734   1.1  christos   if (match == 0 && op_indirect)
   2735   1.1  christos     {
   2736   1.1  christos       opcode = op_indirect;
   2737   1.1  christos       match = 1;
   2738   1.1  christos     }
   2739   1.1  christos 
   2740   1.1  christos   return match ? opcode : 0;
   2741   1.1  christos }
   2742   1.1  christos 
   2743   1.1  christos /* Find the real opcode and its associated operands.  We use a progressive
   2744   1.1  christos    approach here.  On entry, 'opc' points to the first opcode in the
   2745   1.1  christos    table that matches the opcode name in the source line.  We try to
   2746   1.1  christos    isolate an operand, find a possible match in the opcode table.
   2747   1.1  christos    We isolate another operand if no match were found.  The table 'operands'
   2748   1.1  christos    is filled while operands are recognized.
   2749   1.1  christos 
   2750   1.1  christos    Returns the opcode pointer that matches the opcode name in the
   2751   1.1  christos    source line and the associated operands.  */
   2752   1.1  christos static struct m68hc11_opcode *
   2753   1.1  christos find_opcode (struct m68hc11_opcode_def *opc, operand operands[],
   2754   1.1  christos              int *nb_operands)
   2755   1.1  christos {
   2756   1.1  christos   struct m68hc11_opcode *opcode;
   2757   1.1  christos   int i;
   2758   1.1  christos 
   2759   1.1  christos   if (opc->max_operands == 0)
   2760   1.1  christos     {
   2761   1.1  christos       *nb_operands = 0;
   2762   1.1  christos       return opc->opcode;
   2763   1.1  christos     }
   2764   1.1  christos 
   2765   1.1  christos   for (i = 0; i < opc->max_operands;)
   2766   1.1  christos     {
   2767   1.1  christos       int result;
   2768   1.1  christos 
   2769   1.1  christos       result = get_operand (&operands[i], i, opc->format);
   2770   1.1  christos       if (result <= 0)
   2771   1.1  christos 	return 0;
   2772   1.1  christos 
   2773   1.1  christos       /* Special case where the bitmask of the bclr/brclr
   2774   1.1  christos          instructions is not introduced by #.
   2775   1.1  christos          Example: bclr 3,x $80.  */
   2776   1.1  christos       if (i == 1 && (opc->format & M6811_OP_BITMASK)
   2777   1.1  christos 	  && (operands[i].mode & M6811_OP_IND16))
   2778   1.1  christos 	{
   2779   1.1  christos 	  operands[i].mode = M6811_OP_IMM16;
   2780   1.1  christos 	}
   2781   1.1  christos 
   2782   1.1  christos       i += result;
   2783   1.1  christos       *nb_operands = i;
   2784   1.1  christos       if (i >= opc->min_operands)
   2785   1.1  christos 	{
   2786   1.1  christos 	  opcode = find (opc, operands, i);
   2787   1.1  christos 
   2788   1.1  christos           /* Another special case for 'call foo,page' instructions.
   2789   1.1  christos              Since we support 'call foo' and 'call foo,page' we must look
   2790   1.1  christos              if the optional page specification is present otherwise we will
   2791   1.1  christos              assemble immediately and treat the page spec as garbage.  */
   2792   1.1  christos           if (opcode && !(opcode->format & M6812_OP_PAGE))
   2793   1.1  christos              return opcode;
   2794   1.1  christos 
   2795   1.1  christos 	  if (opcode && *input_line_pointer != ',')
   2796   1.1  christos 	    return opcode;
   2797   1.1  christos 	}
   2798   1.1  christos 
   2799   1.1  christos       if (*input_line_pointer == ',')
   2800   1.1  christos 	input_line_pointer++;
   2801   1.1  christos     }
   2802   1.1  christos 
   2803   1.1  christos   return 0;
   2804   1.1  christos }
   2805   1.1  christos 
   2806   1.1  christos #define M6812_XBCC_MARKER (M6812_OP_TBCC_MARKER \
   2807   1.1  christos                            | M6812_OP_DBCC_MARKER \
   2808   1.1  christos                            | M6812_OP_IBCC_MARKER)
   2809   1.1  christos 
   2810   1.1  christos /* Gas line assembler entry point.  */
   2812   1.1  christos 
   2813   1.1  christos /* This is the main entry point for the machine-dependent assembler.  str
   2814   1.1  christos    points to a machine-dependent instruction.  This function is supposed to
   2815  1.10  christos    emit the frags/bytes it assembles to.  */
   2816   1.1  christos void
   2817   1.1  christos md_assemble (char *str)
   2818   1.1  christos {
   2819   1.1  christos   struct m68hc11_opcode_def *opc;
   2820   1.1  christos   struct m68hc11_opcode *opcode;
   2821   1.1  christos 
   2822   1.1  christos   struct m68hc11_opcode opcode_local;
   2823   1.1  christos   char *op_start, *op_end;
   2824   1.1  christos   char *save;
   2825  1.10  christos   char name[20];
   2826   1.1  christos   int nlen = 0;
   2827   1.1  christos   operand operands[M6811_MAX_OPERANDS];
   2828   1.1  christos   int nb_operands = 0;
   2829   1.1  christos   int branch_optimize = 0;
   2830  1.10  christos   int alias_id = -1;
   2831  1.10  christos 
   2832   1.1  christos   /* Drop leading whitespace.  */
   2833   1.1  christos   while (is_whitespace (*str))
   2834   1.1  christos     str++;
   2835   1.1  christos 
   2836   1.1  christos   /* Find the opcode end and get the opcode in 'name'.  The opcode is forced
   2837   1.1  christos      lower case (the opcode table only has lower case op-codes).  */
   2838   1.1  christos   for (op_start = op_end = str;
   2839   1.1  christos        !is_end_of_stmt (*op_end) && !is_whitespace (*op_end);
   2840   1.1  christos        op_end++)
   2841   1.1  christos     {
   2842   1.1  christos       name[nlen] = TOLOWER (op_start[nlen]);
   2843   1.1  christos       nlen++;
   2844   1.1  christos       if (nlen == sizeof (name) - 1)
   2845   1.1  christos 	break;
   2846   1.1  christos     }
   2847   1.1  christos   name[nlen] = 0;
   2848   1.1  christos 
   2849   1.1  christos   if (nlen == 0)
   2850  1.10  christos     {
   2851   1.1  christos       as_bad (_("No instruction or missing opcode."));
   2852   1.1  christos       return;
   2853   1.1  christos     }
   2854   1.1  christos 
   2855   1.1  christos   if (current_architecture == cpuxgate)
   2856   1.1  christos     {
   2857   1.1  christos       /* Find the opcode definition given its name.  */
   2858   1.1  christos       opc = str_hash_find (m68hc11_hash, name);
   2859   1.1  christos       if (opc == NULL)
   2860   1.1  christos         {
   2861   1.1  christos           as_bad (_("Opcode `%s' is not recognized."), name);
   2862   1.1  christos           return;
   2863   1.1  christos         }
   2864  1.10  christos 
   2865   1.1  christos       /* Grab a local copy. */
   2866   1.1  christos       opcode_local.name = opc->opcode->name;
   2867   1.1  christos       /* These will be incomplete where multiple variants exist. */
   2868   1.1  christos       opcode_local.opcode = opc->opcode->opcode;
   2869   1.1  christos       opcode_local.format = opc->opcode->format;
   2870   1.1  christos 
   2871   1.1  christos       save = input_line_pointer;
   2872   1.1  christos       input_line_pointer = op_end;
   2873   1.1  christos 
   2874   1.1  christos       if (opc->format == M68XG_OP_NONE)
   2875   1.8  christos         {
   2876   1.1  christos           /* No special handling required. */
   2877   1.1  christos           opcode_local.format = M68XG_OP_NONE;
   2878   1.1  christos           build_insn_xg (opc->opcode, operands, 0);
   2879   1.1  christos           return;
   2880   1.1  christos         }
   2881   1.1  christos 
   2882   1.1  christos       /* Special handling of TFR. */
   2883   1.1  christos       if (startswith (opc->opcode->name, "tfr"))
   2884   1.1  christos         {
   2885   1.1  christos           /* There must be two operands with a comma. */
   2886   1.1  christos           input_line_pointer = skip_whites (input_line_pointer);
   2887   1.1  christos           operands[0].reg1 = register_name ();
   2888   1.1  christos           if (operands[0].reg1 == REG_NONE)
   2889   1.1  christos             {
   2890   1.1  christos               as_bad ("Invalid register\n");
   2891   1.1  christos               return;
   2892   1.1  christos             }
   2893   1.1  christos           input_line_pointer = skip_whites (input_line_pointer);
   2894   1.1  christos           if (*input_line_pointer != ',')
   2895   1.1  christos             {
   2896   1.1  christos               as_bad ("Missing comma.\n");
   2897   1.1  christos               return;
   2898   1.1  christos             }
   2899   1.1  christos           input_line_pointer++;
   2900   1.1  christos           input_line_pointer = skip_whites (input_line_pointer);
   2901   1.1  christos           operands[1].reg1 = register_name ();
   2902   1.1  christos           if (operands[1].reg1 == REG_NONE)
   2903   1.1  christos             {
   2904   1.1  christos               as_bad ("Invalid register\n");
   2905   1.1  christos               return;
   2906   1.1  christos             }
   2907   1.1  christos           input_line_pointer = skip_whites (input_line_pointer);
   2908   1.1  christos           if (*input_line_pointer != '\n' && *input_line_pointer)
   2909   1.1  christos             {
   2910   1.1  christos               as_bad (_("Garbage at end of instruction: `%s'."),
   2911   1.1  christos 		      input_line_pointer);
   2912   1.1  christos               return;
   2913   1.1  christos             }
   2914   1.1  christos           if (operands[1].reg1 == REG_CCR) /* ,CCR */
   2915   1.1  christos 	    opc->opcode->opcode = 0x00f8 | ( operands[0].reg1 << 8);
   2916   1.1  christos           else if (operands[0].reg1 == REG_CCR) /* CCR, */
   2917   1.1  christos 	    opc->opcode->opcode = 0x00f9 | ( operands[1].reg1 << 8);
   2918   1.1  christos           else if (operands[1].reg1 == REG_PC) /* ,PC */
   2919   1.1  christos 	    opc->opcode->opcode = 0x00fa | ( operands[0].reg1 << 8);
   2920   1.1  christos           else
   2921   1.1  christos             {
   2922   1.1  christos               as_bad ("Invalid operand to TFR\n");
   2923   1.1  christos               return;
   2924   1.1  christos             }
   2925   1.1  christos           /* no special handling required */
   2926   1.1  christos           opcode_local.format = M68XG_OP_NONE;
   2927   1.1  christos           opcode_local.opcode = opc->opcode->opcode;
   2928   1.1  christos           build_insn_xg (&opcode_local, operands, 0);
   2929   1.1  christos           return;
   2930   1.1  christos 	}
   2931   1.1  christos 
   2932   1.1  christos       /* CSEM, SSEM */
   2933   1.1  christos       if (opc->format & M68XG_OP_IMM3)
   2934   1.1  christos         {
   2935   1.1  christos 	  /* Either IMM3 or R */
   2936   1.1  christos           input_line_pointer = skip_whites (input_line_pointer);
   2937   1.1  christos           if ((*input_line_pointer == 'R') || (*input_line_pointer == 'r'))
   2938   1.1  christos             {
   2939   1.1  christos               operands[0].reg1 = register_name ();
   2940   1.1  christos               if (operands[0].reg1 == REG_NONE)
   2941   1.1  christos                 {
   2942   1.1  christos                   as_bad ("Invalid register\n");
   2943   1.1  christos                   return;
   2944   1.1  christos                 }
   2945   1.1  christos               operands[0].mode = M68XG_OP_R;
   2946   1.1  christos               /* One opcode has multiple modes, so find right one. */
   2947   1.1  christos               opcode = find (opc, operands, 1);
   2948   1.1  christos               if (opcode)
   2949   1.3  christos               	{
   2950   1.1  christos                   opcode_local.opcode = opcode->opcode
   2951   1.1  christos 		    | (operands[0].reg1 << 8);
   2952   1.1  christos                   opcode_local.format = M68XG_OP_NONE;
   2953   1.1  christos                   build_insn_xg (&opcode_local, operands, 1);
   2954   1.1  christos 		}
   2955   1.1  christos 	      else
   2956   1.1  christos 		as_bad ("No opcode found\n");
   2957   1.1  christos 
   2958   1.1  christos               return;
   2959   1.1  christos             }
   2960   1.1  christos           else
   2961   1.1  christos             {
   2962   1.1  christos               if (*input_line_pointer == '#')
   2963   1.1  christos                 input_line_pointer++;
   2964   1.1  christos 
   2965   1.1  christos               expression (&operands[0].exp);
   2966   1.1  christos               if (operands[0].exp.X_op == O_illegal)
   2967   1.1  christos               	{
   2968   1.1  christos                   as_bad (_("Illegal operand."));
   2969   1.1  christos                   return;
   2970   1.1  christos               	}
   2971   1.1  christos               else if (operands[0].exp.X_op == O_absent)
   2972   1.1  christos               	{
   2973   1.3  christos                   as_bad (_("Missing operand."));
   2974   1.1  christos                   return;
   2975   1.1  christos               	}
   2976   1.1  christos 
   2977   1.1  christos               if (check_range (operands[0].exp.X_add_number,M68XG_OP_IMM3))
   2978   1.1  christos               	{
   2979   1.1  christos 		  opcode_local.opcode |= (operands[0].exp.X_add_number);
   2980   1.1  christos 		  operands[0].mode = M68XG_OP_IMM3;
   2981   1.1  christos 
   2982   1.1  christos 		  opcode = find (opc, operands, 1);
   2983   1.1  christos                   if (opcode)
   2984   1.1  christos                     {
   2985   1.1  christos 		      opcode_local.opcode = opcode->opcode;
   2986   1.1  christos 		      opcode_local.opcode
   2987   1.1  christos 			|= (operands[0].exp.X_add_number) << 8;
   2988   1.1  christos 		      opcode_local.format = M68XG_OP_NONE;
   2989   1.1  christos 		      build_insn_xg (&opcode_local, operands, 1);
   2990   1.1  christos                     }
   2991   1.1  christos                   else
   2992   1.1  christos                     as_bad ("No opcode found\n");
   2993   1.1  christos 
   2994   1.1  christos                   return;
   2995   1.1  christos                 }
   2996   1.1  christos               else
   2997   1.8  christos                 {
   2998   1.1  christos                   as_bad ("Number out of range for IMM3\n");
   2999   1.1  christos                   return;
   3000   1.1  christos                 }
   3001   1.1  christos             }
   3002   1.1  christos 	}
   3003   1.1  christos 
   3004   1.1  christos       /* Special handling of SIF. */
   3005   1.1  christos       if (startswith (opc->opcode->name, "sif"))
   3006   1.1  christos         {
   3007   1.1  christos           /* Either OP_NONE or OP_RS. */
   3008   1.1  christos           if (*input_line_pointer != '\n')
   3009   1.1  christos 	    input_line_pointer = skip_whites (input_line_pointer);
   3010   1.1  christos 
   3011   1.1  christos           if ((*input_line_pointer == '\n') || (*input_line_pointer == '\r')
   3012   1.1  christos               || (*input_line_pointer == '\0'))
   3013   1.1  christos 	    opc->opcode->opcode = 0x0300;
   3014   1.1  christos           else
   3015   1.1  christos             {
   3016   1.1  christos               operands[0].reg1 = register_name ();
   3017   1.1  christos               if (operands[0].reg1 == REG_NONE)
   3018   1.1  christos 		{
   3019   1.1  christos                   as_bad ("Invalid register\n");
   3020   1.1  christos                   return;
   3021   1.1  christos 		}
   3022   1.1  christos               opcode_local.opcode = 0x00f7 | (operands[0].reg1 << 8);
   3023   1.1  christos             }
   3024   1.1  christos           opcode_local.format = M68XG_OP_NONE;
   3025   1.1  christos           build_insn_xg (&opcode_local, operands, 0);
   3026   1.1  christos           return;
   3027   1.1  christos         }
   3028   1.1  christos 
   3029   1.1  christos       /* SEX, PAR, JAL plus aliases NEG, TST, COM */
   3030   1.1  christos       if (opc->format & M68XG_OP_R)
   3031   1.1  christos         {
   3032   1.1  christos           input_line_pointer = skip_whites (input_line_pointer);
   3033   1.1  christos           operands[0].reg1 = register_name ();
   3034   1.1  christos           if (operands[0].reg1 == REG_NONE)
   3035   1.1  christos             {
   3036   1.1  christos               as_bad ("Invalid register\n");
   3037   1.1  christos               return;
   3038   1.1  christos             }
   3039   1.1  christos           if ((*input_line_pointer == '\n') || (*input_line_pointer == '\r')
   3040   1.1  christos               || (*input_line_pointer == '\0'))
   3041   1.1  christos             {
   3042   1.8  christos               /* Likely to be OP R. */
   3043   1.8  christos               if (opc->format & M68XG_OP_R)
   3044   1.1  christos                 {
   3045   1.1  christos                   operands[0].mode = M68XG_OP_R;
   3046   1.1  christos 
   3047   1.1  christos                   opcode = find (opc, operands, 1);
   3048   1.8  christos                   if (opcode)
   3049   1.1  christos 		    {
   3050   1.1  christos                       if ((startswith (opc->opcode->name, "com"))
   3051   1.1  christos                           || (startswith (opc->opcode->name, "neg")))
   3052   1.1  christos                         /* Special case for com RD as alias for sub RD,R0,RS */
   3053   1.1  christos                         /* Special case for neg RD as alias for sub RD,R0,RS */
   3054   1.1  christos                         opcode_local.opcode = opcode->opcode
   3055   1.1  christos                           | (operands[0].reg1 << 8) | (operands[0].reg1 << 2);
   3056   1.1  christos 		      else if (startswith (opc->opcode->name, "tst"))
   3057   1.1  christos                         /* Special case for tst RS alias for sub R0, RS, R0 */
   3058   1.1  christos                         opcode_local.opcode = opcode->opcode
   3059   1.1  christos                           | (operands[0].reg1 << 5);
   3060   1.1  christos                       else
   3061   1.1  christos                         opcode_local.opcode |= (operands[0].reg1 << 8);
   3062   1.1  christos                     }
   3063   1.1  christos                   opcode_local.format = M68XG_OP_NONE;
   3064   1.1  christos                   build_insn_xg (&opcode_local, operands, 0);
   3065   1.1  christos                 }
   3066   1.1  christos               else
   3067   1.3  christos 		as_bad ("No valid mode found\n");
   3068   1.1  christos 
   3069   1.1  christos               return;
   3070   1.1  christos             }
   3071   1.1  christos         }
   3072   1.1  christos 
   3073   1.1  christos       if (opc->format & (M68XG_OP_REL9 | M68XG_OP_REL10))
   3074   1.1  christos         {
   3075   1.1  christos           opcode_local.format = opc->format;
   3076   1.1  christos           input_line_pointer = skip_whites (input_line_pointer);
   3077   1.1  christos           expression (&operands[0].exp);
   3078   1.1  christos           if (operands[0].exp.X_op == O_illegal)
   3079   1.1  christos             {
   3080   1.1  christos               as_bad (_("Illegal operand."));
   3081   1.1  christos               return;
   3082   1.1  christos             }
   3083   1.1  christos           else if (operands[0].exp.X_op == O_absent)
   3084   1.1  christos             {
   3085   1.1  christos               as_bad (_("Missing operand."));
   3086   1.1  christos               return;
   3087   1.1  christos             }
   3088   1.1  christos           opcode_local.opcode = opc->opcode->opcode;
   3089   1.1  christos           build_insn_xg (&opcode_local, operands, 1);
   3090   1.1  christos           return;
   3091   1.1  christos         }
   3092   1.1  christos 
   3093   1.3  christos 
   3094   1.1  christos       /* For other command formats, parse input line and determine the mode
   3095   1.1  christos          we are using as we go. */
   3096   1.1  christos 
   3097   1.1  christos       input_line_pointer = skip_whites (input_line_pointer);
   3098   1.3  christos       if ((*input_line_pointer == '\n') || (*input_line_pointer == '\r')
   3099   1.1  christos           || (*input_line_pointer == '\0'))
   3100   1.1  christos         return; /* nothing left */
   3101   1.1  christos 
   3102   1.1  christos       if (*input_line_pointer == '#')
   3103   1.1  christos         {
   3104   1.1  christos           as_bad ("No register specified before hash\n");
   3105   1.1  christos           return;
   3106   1.1  christos         }
   3107   1.1  christos 
   3108   1.1  christos       /* first operand is expected to be a register */
   3109   1.1  christos       if ((*input_line_pointer == 'R') || (*input_line_pointer == 'r'))
   3110   1.1  christos         {
   3111   1.1  christos           operands[0].reg1 = register_name ();
   3112   1.1  christos           if (operands[0].reg1 == REG_NONE)
   3113   1.1  christos             {
   3114   1.1  christos               as_bad ("Invalid register\n");
   3115   1.1  christos               return;
   3116   1.1  christos             }
   3117   1.1  christos         }
   3118   1.1  christos 
   3119   1.1  christos       input_line_pointer = skip_whites (input_line_pointer);
   3120   1.1  christos       if (*input_line_pointer != ',')
   3121   1.1  christos         {
   3122   1.1  christos           as_bad ("Missing operand\n");
   3123   1.1  christos           return;
   3124   1.1  christos         }
   3125   1.1  christos       input_line_pointer++;
   3126   1.1  christos       input_line_pointer = skip_whites (input_line_pointer);
   3127   1.1  christos 
   3128   1.1  christos       if (*input_line_pointer == '#')
   3129   1.1  christos         {
   3130   1.8  christos           /* Some kind of immediate mode, check if this is possible. */
   3131   1.1  christos           if (!(opc->format
   3132   1.1  christos 		& (M68XG_OP_R_IMM8 | M68XG_OP_R_IMM16 | M68XG_OP_R_IMM4)))
   3133   1.1  christos             as_bad ("Invalid immediate mode for `%s'", opc->opcode->name);
   3134   1.1  christos           else
   3135   1.8  christos             {
   3136   1.1  christos               input_line_pointer++;
   3137   1.1  christos               input_line_pointer = skip_whites (input_line_pointer);
   3138   1.1  christos               if (startswith (input_line_pointer, "%hi"))
   3139   1.1  christos                 {
   3140   1.1  christos                   input_line_pointer += 3;
   3141   1.1  christos                   operands[0].mode = M6811_OP_HIGH_ADDR;
   3142   1.1  christos                 }
   3143   1.1  christos               else if (startswith (input_line_pointer, "%lo"))
   3144   1.1  christos                 {
   3145   1.1  christos 		  input_line_pointer += 3;
   3146   1.1  christos 		  operands[0].mode = M6811_OP_LOW_ADDR;
   3147   1.1  christos                 }
   3148   1.1  christos               else
   3149   1.1  christos 		operands[0].mode = 0;
   3150   1.1  christos 
   3151   1.1  christos               expression (&operands[0].exp);
   3152   1.1  christos               if (operands[0].exp.X_op == O_illegal)
   3153   1.1  christos                 {
   3154   1.1  christos                   as_bad (_("Illegal operand."));
   3155   1.1  christos                   return;
   3156   1.1  christos                 }
   3157   1.1  christos               else if (operands[0].exp.X_op == O_absent)
   3158   1.1  christos                 {
   3159   1.1  christos                   as_bad (_("Missing operand."));
   3160   1.1  christos                   return;
   3161   1.1  christos                 }
   3162   1.1  christos               /* ok so far, can only be one mode */
   3163   1.1  christos               opcode_local.format = opc->format
   3164   1.1  christos 		& (M68XG_OP_R_IMM8 | M68XG_OP_R_IMM16 | M68XG_OP_R_IMM4);
   3165   1.3  christos               if (opcode_local.format & M68XG_OP_R_IMM4)
   3166   1.1  christos                 {
   3167   1.1  christos                   operands[0].mode = M68XG_OP_R_IMM4;
   3168   1.1  christos                   /* same opcodes have multiple modes, so find right one */
   3169   1.1  christos                   opcode = find (opc, operands, 1);
   3170   1.3  christos                   if (opcode)
   3171   1.1  christos 		    opcode_local.opcode = opcode->opcode
   3172   1.1  christos 		      | (operands[0].reg1 << 8);
   3173   1.1  christos 
   3174   1.1  christos                   if (operands[0].exp.X_op != O_constant)
   3175   1.1  christos                     as_bad ("Only constants supported at for IMM4 mode\n");
   3176   1.1  christos                   else
   3177   1.1  christos                     {
   3178   1.1  christos                       if (check_range
   3179   1.1  christos                           (operands[0].exp.X_add_number,M68XG_OP_R_IMM4))
   3180   1.1  christos                         opcode_local.opcode
   3181   1.1  christos 			  |= (operands[0].exp.X_add_number << 4);
   3182   1.1  christos                       else
   3183   1.1  christos                         as_bad ("Number out of range for IMM4\n");
   3184   1.1  christos                     }
   3185   1.1  christos                   opcode_local.format = M68XG_OP_NONE;
   3186   1.1  christos                 }
   3187   1.1  christos               else if (opcode_local.format & M68XG_OP_R_IMM16)
   3188   1.1  christos                 {
   3189   1.1  christos                   operands[0].mode = M68XG_OP_R_IMM16;
   3190   1.1  christos 
   3191   1.1  christos                   opcode = find (opc, operands, 1);
   3192   1.1  christos                   if (opcode)
   3193   1.1  christos                     {
   3194   1.1  christos                       opcode_local.opcode = opcode->opcode
   3195   1.1  christos 			| (operands[0].reg1 << 8);
   3196   1.1  christos                     }
   3197   1.1  christos                 }
   3198   1.1  christos               else
   3199   1.1  christos                 {
   3200   1.1  christos                   opcode_local.opcode = opc->opcode->opcode
   3201   1.1  christos 		    | (operands[0].reg1 << 8);
   3202   1.1  christos                 }
   3203   1.1  christos               build_insn_xg (&opcode_local, operands, 1);
   3204   1.1  christos             }
   3205   1.1  christos         }
   3206   1.1  christos       else if ((*input_line_pointer == 'R') || (*input_line_pointer == 'r'))
   3207   1.1  christos         {
   3208   1.1  christos           /* we've got as far as OP R, R */
   3209   1.1  christos           operands[1].reg1 = register_name ();
   3210   1.1  christos           if (operands[1].reg1 == REG_NONE)
   3211   1.1  christos             {
   3212   1.1  christos               as_bad ("Invalid register\n");
   3213   1.1  christos               return;
   3214   1.1  christos             }
   3215   1.1  christos           if ((*input_line_pointer == '\n') || (*input_line_pointer == '\r')
   3216   1.1  christos 	      || (*input_line_pointer == '\0'))
   3217   1.1  christos             {
   3218   1.8  christos               /* looks like OP_R_R */
   3219   1.8  christos               if (opc->format & M68XG_OP_R_R)
   3220   1.8  christos                 {
   3221   1.1  christos                   operands[0].mode = M68XG_OP_R_R;
   3222   1.1  christos                   /* same opcodes have multiple modes, so find right one */
   3223   1.1  christos                   opcode = find (opc, operands, 1);
   3224   1.1  christos                   if (opcode)
   3225   1.1  christos                     {
   3226   1.3  christos                       if ((startswith (opc->opcode->name, "com"))
   3227   1.1  christos 			  || (startswith (opc->opcode->name, "mov"))
   3228   1.1  christos 			  || (startswith (opc->opcode->name, "neg")))
   3229   1.8  christos                         {
   3230   1.8  christos                           /* Special cases for:
   3231   1.1  christos                              com RD, RS alias for xnor RD,R0,RS
   3232   1.1  christos                              mov RD, RS alias for or RD, R0, RS
   3233   1.1  christos                              neg RD, RS alias for sub RD, R0, RS */
   3234   1.1  christos                           opcode_local.opcode = opcode->opcode
   3235   1.3  christos                             | (operands[0].reg1 << 8) | (operands[1].reg1 << 2);
   3236   1.1  christos                         }
   3237   1.1  christos                       else if ((startswith (opc->opcode->name, "cmp"))
   3238   1.1  christos 			       || (startswith (opc->opcode->name, "cpc")))
   3239   1.1  christos                         {
   3240   1.1  christos                           /* special cases for:
   3241   1.1  christos                              cmp RS1, RS2 alias for sub R0, RS1, RS2
   3242   1.1  christos                              cpc RS1, RS2 alias for sbc R0, RS1, RS2 */
   3243   1.1  christos                           opcode_local.opcode = opcode->opcode
   3244   1.1  christos 			    | (operands[0].reg1 << 5) | (operands[1].reg1 << 2);
   3245   1.1  christos                         }
   3246   1.1  christos                       else
   3247   1.1  christos                         {
   3248   1.1  christos                           opcode_local.opcode = opcode->opcode
   3249   1.1  christos                             | (operands[0].reg1 << 8) | (operands[1].reg1 << 5);
   3250   1.1  christos                         }
   3251   1.1  christos                       opcode_local.format = M68XG_OP_NONE;
   3252   1.1  christos                       build_insn_xg (&opcode_local, operands, 1);
   3253   1.1  christos                     }
   3254   1.1  christos                 }
   3255   1.1  christos               else
   3256   1.1  christos                 {
   3257   1.1  christos                   as_bad ("No valid mode found\n");
   3258   1.1  christos                 }
   3259   1.1  christos             }
   3260   1.1  christos           else
   3261   1.1  christos             {
   3262   1.1  christos               /* more data */
   3263   1.1  christos               if (*input_line_pointer != ',')
   3264   1.1  christos                 {
   3265   1.1  christos                   as_bad (_("Missing operand."));
   3266   1.1  christos                   return;
   3267   1.1  christos                 }
   3268   1.1  christos               input_line_pointer++;
   3269   1.1  christos               input_line_pointer = skip_whites (input_line_pointer);
   3270   1.1  christos               if ((*input_line_pointer == 'R') || (*input_line_pointer == 'r'))
   3271   1.1  christos                 {
   3272   1.1  christos                   operands[2].reg1 = register_name ();
   3273   1.1  christos                   if (operands[2].reg1 == REG_NONE)
   3274   1.1  christos                     {
   3275   1.1  christos                       as_bad ("Invalid register\n");
   3276   1.1  christos                       return;
   3277   1.3  christos                     }
   3278   1.1  christos                   if (opc->format & M68XG_OP_R_R_R)
   3279   1.1  christos                     {
   3280   1.1  christos                       operands[0].mode = M68XG_OP_R_R_R;
   3281   1.1  christos 
   3282   1.1  christos                       opcode = find (opc, operands, 1);
   3283   1.1  christos                       if (opcode)
   3284   1.1  christos                         {
   3285   1.1  christos                           opcode_local.opcode = opcode->opcode
   3286   1.1  christos                             | (operands[0].reg1 << 8) | (operands[1].reg1 << 5)
   3287   1.1  christos                             | (operands[2].reg1 << 2);
   3288   1.1  christos                           opcode_local.format = M68XG_OP_NONE;
   3289   1.1  christos                           build_insn_xg (&opcode_local, operands, 1);
   3290   1.1  christos                         }
   3291   1.1  christos                     }
   3292   1.1  christos                   else
   3293   1.1  christos                     {
   3294   1.1  christos                       as_bad ("No valid mode found\n");
   3295   1.1  christos                     }
   3296   1.1  christos                 }
   3297   1.1  christos             }
   3298   1.1  christos         }
   3299   1.1  christos       else if (*input_line_pointer == '(') /* Indexed modes */
   3300   1.1  christos         {
   3301   1.1  christos           input_line_pointer++;
   3302   1.1  christos           input_line_pointer = skip_whites (input_line_pointer);
   3303   1.1  christos           if ((*input_line_pointer == 'R') || (*input_line_pointer == 'r'))
   3304   1.1  christos             {
   3305   1.1  christos               /* we've got as far as OP R, (R */
   3306   1.1  christos               operands[1].reg1 = register_name ();
   3307   1.1  christos               if (operands[1].reg1 == REG_NONE)
   3308   1.1  christos                 {
   3309   1.1  christos                   as_bad ("Invalid register\n");
   3310   1.1  christos                   return;
   3311   1.1  christos                 }
   3312   1.1  christos 
   3313   1.1  christos               if ((*input_line_pointer == '\n') || (*input_line_pointer == '\r')
   3314   1.3  christos 		  || (*input_line_pointer == '\0'))
   3315   1.1  christos                 {
   3316   1.1  christos                   /* Looks like OP_R_R. */
   3317   1.1  christos                   as_bad (_("Missing operand."));
   3318   1.1  christos                   return;
   3319   1.1  christos                 }
   3320   1.1  christos 
   3321   1.1  christos               input_line_pointer = skip_whites (input_line_pointer);
   3322   1.1  christos 
   3323   1.1  christos               if (*input_line_pointer != ',')
   3324   1.1  christos                 {
   3325   1.1  christos                   as_bad (_("Missing operand."));
   3326   1.1  christos                   return;
   3327   1.1  christos                 }
   3328   1.1  christos               input_line_pointer++;
   3329   1.1  christos               input_line_pointer = skip_whites (input_line_pointer);
   3330   1.1  christos 
   3331   1.1  christos               if (*input_line_pointer == '#')
   3332   1.1  christos                 {
   3333   1.1  christos                   input_line_pointer++;
   3334   1.1  christos                   input_line_pointer = skip_whites (input_line_pointer);
   3335   1.1  christos                   expression (&operands[0].exp);
   3336   1.1  christos                   if (operands[0].exp.X_op == O_illegal)
   3337   1.1  christos                     {
   3338   1.1  christos                       as_bad (_("Illegal operand."));
   3339   1.1  christos                       return;
   3340   1.1  christos                     }
   3341   1.1  christos                   else if (operands[0].exp.X_op == O_absent)
   3342   1.1  christos                     {
   3343   1.1  christos                       as_bad (_("Missing operand."));
   3344   1.1  christos                       return;
   3345   1.1  christos                     }
   3346   1.1  christos 
   3347   1.1  christos                   input_line_pointer = skip_whites (input_line_pointer);
   3348   1.1  christos                   if (*input_line_pointer != ')')
   3349   1.3  christos                     {
   3350   1.1  christos 		      as_bad ("Missing `)' to close register indirect operand.");
   3351   1.1  christos                       return;
   3352   1.1  christos                     }
   3353   1.1  christos                   else
   3354   1.1  christos                     {
   3355   1.1  christos                       input_line_pointer++;
   3356   1.1  christos                     }
   3357   1.1  christos 
   3358   1.1  christos                   /* Ok so far, can only be one mode. */
   3359   1.1  christos                   opcode_local.format = M68XG_OP_R_R_OFFS5;
   3360   1.1  christos                   operands[0].mode = M68XG_OP_R_R_OFFS5;
   3361   1.1  christos 
   3362   1.1  christos                   opcode = find (opc, operands, 1);
   3363   1.1  christos                   if (opcode)
   3364   1.1  christos                     {
   3365   1.1  christos                       opcode_local.opcode = opcode->opcode
   3366   1.1  christos                         | (operands[0].reg1 << 8) | (operands[1].reg1 << 5);
   3367   1.1  christos                       if (operands[0].exp.X_op != O_constant)
   3368   1.1  christos                         {
   3369   1.1  christos                           as_bad
   3370   1.1  christos                             ("Only constants supported for indexed OFFS5 mode\n");
   3371   1.1  christos                         }
   3372   1.1  christos                       else
   3373   1.1  christos                         {
   3374   1.1  christos                           if (check_range (operands[0].exp.X_add_number,
   3375   1.1  christos 					   M68XG_OP_R_R_OFFS5))
   3376   1.1  christos                             {
   3377   1.1  christos                               opcode_local.opcode
   3378   1.1  christos 				|= (operands[0].exp.X_add_number);
   3379   1.1  christos                               opcode_local.format = M68XG_OP_NONE;
   3380   1.1  christos                               build_insn_xg (&opcode_local, operands, 1);
   3381   1.1  christos                             }
   3382   1.1  christos                           else
   3383   1.1  christos                             {
   3384   1.1  christos                               as_bad ("Number out of range for OFFS5\n");
   3385   1.1  christos                             }
   3386   1.1  christos                         }
   3387   1.1  christos                     }
   3388   1.1  christos                 }
   3389   1.1  christos               else
   3390   1.1  christos                 {
   3391   1.1  christos                   operands[0].mode = M68XG_OP_RD_RB_RI;
   3392   1.1  christos 
   3393   1.1  christos                   if (*input_line_pointer == '-')
   3394   1.1  christos                     {
   3395   1.1  christos                       operands[0].mode = M68XG_OP_RD_RB_mRI;
   3396   1.1  christos                       input_line_pointer++;
   3397   1.1  christos                     }
   3398   1.1  christos                   operands[2].reg1 = register_name ();
   3399   1.1  christos                   if (operands[2].reg1 == REG_NONE)
   3400   1.1  christos                     {
   3401   1.1  christos                       as_bad ("Invalid register\n");
   3402   1.1  christos                       return;
   3403   1.1  christos                     }
   3404   1.1  christos 
   3405   1.1  christos                   if (*input_line_pointer == '+')
   3406   1.1  christos                     {
   3407   1.1  christos                       if (opcode_local.format == M68XG_OP_RD_RB_mRI)
   3408   1.1  christos                         {
   3409   1.1  christos                           as_bad (_("Illegal operand."));
   3410   1.1  christos                           return;
   3411   1.1  christos                         }
   3412   1.1  christos                       operands[0].mode = M68XG_OP_RD_RB_RIp;
   3413   1.1  christos                       input_line_pointer++;
   3414   1.1  christos                     }
   3415   1.1  christos 
   3416   1.1  christos                   input_line_pointer = skip_whites (input_line_pointer);
   3417   1.1  christos                   if (*input_line_pointer != ')')
   3418   1.1  christos                     {
   3419   1.1  christos 		      as_bad
   3420   1.1  christos                         ("Missing `)' to close register indirect operand.");
   3421   1.1  christos                       return;
   3422   1.1  christos                     }
   3423   1.1  christos                   else
   3424   1.1  christos                     {
   3425   1.1  christos                       input_line_pointer++;
   3426   1.1  christos                     }
   3427   1.1  christos 
   3428   1.1  christos                   opcode = find (opc, operands, 1);
   3429   1.1  christos                   if (opcode)
   3430   1.1  christos                     {
   3431   1.1  christos                       opcode_local.opcode = opcode->opcode
   3432  1.10  christos                         | (operands[0].reg1 << 8) | (operands[1].reg1 << 5)
   3433   1.1  christos                         | (operands[2].reg1 << 2);
   3434   1.1  christos                       opcode_local.format = M68XG_OP_NONE;
   3435   1.1  christos                       build_insn_xg (&opcode_local, operands, 1);
   3436   1.1  christos                     }
   3437   1.1  christos                   else
   3438   1.1  christos                     {
   3439   1.1  christos                       as_bad ("Failed to find opcode for %s %s\n",
   3440   1.1  christos 			      opc->opcode->name, op_end);
   3441   1.1  christos                     }
   3442   1.1  christos                 }
   3443   1.1  christos             }
   3444   1.1  christos         }
   3445   1.1  christos       else
   3446   1.1  christos         {
   3447  1.10  christos 	  as_bad (_("Failed to find a valid mode for `%s'."),
   3448   1.1  christos 		  opc->opcode->name);
   3449   1.1  christos         }
   3450   1.1  christos 
   3451   1.1  christos       if (opc->opcode && !flag_mri)
   3452   1.1  christos         {
   3453   1.1  christos           char *p = input_line_pointer;
   3454   1.1  christos 
   3455   1.1  christos           while (is_whitespace (*p) || *p == '\n' || *p == '\r')
   3456   1.1  christos 	    p++;
   3457   1.1  christos 
   3458   1.1  christos           if (*p != '\n' && *p)
   3459   1.1  christos             as_bad (_("Garbage at end of instruction: `%s'."), p);
   3460   1.1  christos         }
   3461   1.1  christos 
   3462   1.1  christos       input_line_pointer = save;
   3463   1.1  christos 
   3464   1.1  christos       /* Opcode is known but does not have valid operands.  Print out the
   3465   1.1  christos          syntax for this opcode.  */
   3466   1.1  christos       if (opc->opcode == 0)
   3467   1.1  christos         {
   3468   1.1  christos           if (flag_print_insn_syntax)
   3469   1.1  christos             print_insn_format (name);
   3470   1.1  christos 
   3471  1.10  christos           as_bad (_("Invalid operand for `%s'"), name);
   3472   1.1  christos           return;
   3473   1.1  christos         }
   3474   1.1  christos 
   3475   1.1  christos       return;
   3476   1.1  christos     }
   3477   1.1  christos 
   3478   1.1  christos   /* Find the opcode definition given its name.  */
   3479  1.10  christos   opc = str_hash_find (m68hc11_hash, name);
   3480   1.1  christos 
   3481   1.1  christos   /* If it's not recognized, look for 'jbsr' and 'jbxx'.  These are
   3482   1.1  christos      pseudo insns for relative branch.  For these branches, we always
   3483   1.1  christos      optimize them (turned into absolute branches) even if --short-branches
   3484   1.1  christos      is given.  */
   3485   1.1  christos   if (opc == NULL && name[0] == 'j' && name[1] == 'b')
   3486   1.1  christos     {
   3487   1.1  christos       opc = str_hash_find (m68hc11_hash, &name[1]);
   3488   1.1  christos       if (opc
   3489   1.1  christos 	  && (!(opc->format & M6811_OP_JUMP_REL)
   3490   1.1  christos 	      || (opc->format & M6811_OP_BITMASK)))
   3491   1.1  christos 	opc = 0;
   3492  1.10  christos       if (opc)
   3493   1.1  christos 	branch_optimize = 1;
   3494  1.10  christos     }
   3495   1.1  christos 
   3496   1.1  christos   /* The following test should probably be removed.  This does not conform
   3497   1.1  christos      to Motorola assembler specs.  */
   3498   1.1  christos   if (opc == NULL && flag_mri)
   3499  1.10  christos     {
   3500  1.10  christos       if (is_whitespace (*op_end))
   3501   1.1  christos 	{
   3502   1.1  christos 	  while (is_whitespace (*op_end))
   3503   1.1  christos 	    op_end++;
   3504   1.1  christos 
   3505   1.1  christos 	  if (nlen < 19
   3506   1.1  christos 	      && (*op_end &&
   3507   1.1  christos 		  (is_end_of_stmt (op_end[1])
   3508   1.1  christos 		   || is_whitespace (op_end[1])
   3509   1.1  christos 		   || !ISALNUM (op_end[1])))
   3510  1.10  christos 	      && (*op_end == 'a' || *op_end == 'b'
   3511   1.1  christos 		  || *op_end == 'A' || *op_end == 'B'
   3512   1.1  christos 		  || *op_end == 'd' || *op_end == 'D'
   3513   1.1  christos 		  || *op_end == 'x' || *op_end == 'X'
   3514   1.1  christos 		  || *op_end == 'y' || *op_end == 'Y'))
   3515   1.1  christos 	    {
   3516   1.1  christos 	      name[nlen++] = TOLOWER (*op_end++);
   3517   1.1  christos 	      name[nlen] = 0;
   3518   1.1  christos 	      opc = str_hash_find (m68hc11_hash, name);
   3519   1.1  christos 	    }
   3520   1.1  christos 	}
   3521   1.1  christos     }
   3522   1.1  christos 
   3523   1.1  christos   /* Identify a possible instruction alias.  There are some on the
   3524   1.1  christos      68HC12 to emulate a few 68HC11 instructions.  */
   3525   1.1  christos   if (opc == NULL && (current_architecture & cpu6812))
   3526   1.1  christos     {
   3527   1.1  christos       int i;
   3528   1.1  christos 
   3529   1.1  christos       for (i = 0; i < m68hc12_num_alias; i++)
   3530   1.1  christos 	if (strcmp (m68hc12_alias[i].name, name) == 0)
   3531   1.1  christos 	  {
   3532   1.1  christos 	    alias_id = i;
   3533   1.1  christos 	    break;
   3534  1.10  christos 	  }
   3535   1.1  christos     }
   3536   1.1  christos   if (opc == NULL && alias_id < 0)
   3537   1.1  christos     {
   3538   1.1  christos       as_bad (_("Opcode `%s' is not recognized."), name);
   3539   1.1  christos       return;
   3540   1.1  christos     }
   3541   1.1  christos   save = input_line_pointer;
   3542   1.1  christos   input_line_pointer = op_end;
   3543   1.1  christos 
   3544   1.1  christos   if (opc)
   3545   1.1  christos     {
   3546   1.1  christos       opc->used++;
   3547   1.1  christos       opcode = find_opcode (opc, operands, &nb_operands);
   3548  1.10  christos     }
   3549   1.1  christos   else
   3550   1.1  christos     opcode = 0;
   3551   1.1  christos 
   3552   1.1  christos   if ((opcode || alias_id >= 0) && !flag_mri)
   3553   1.1  christos     {
   3554   1.1  christos       char *p = input_line_pointer;
   3555   1.1  christos 
   3556   1.1  christos       while (is_whitespace (*p) || *p == '\n' || *p == '\r')
   3557   1.1  christos 	p++;
   3558   1.1  christos 
   3559   1.1  christos       if (*p != '\n' && *p)
   3560   1.1  christos 	as_bad (_("Garbage at end of instruction: `%s'."), p);
   3561   1.1  christos     }
   3562   1.1  christos 
   3563   1.1  christos   input_line_pointer = save;
   3564   1.1  christos 
   3565   1.1  christos   if (alias_id >= 0)
   3566   1.1  christos     {
   3567   1.1  christos       char *f = m68hc11_new_insn (m68hc12_alias[alias_id].size);
   3568   1.1  christos 
   3569   1.1  christos       number_to_chars_bigendian (f, m68hc12_alias[alias_id].code1, 1);
   3570   1.1  christos       if (m68hc12_alias[alias_id].size > 1)
   3571   1.1  christos 	number_to_chars_bigendian (f + 1, m68hc12_alias[alias_id].code2, 1);
   3572   1.1  christos 
   3573   1.1  christos       return;
   3574   1.1  christos     }
   3575   1.1  christos 
   3576   1.1  christos   /* Opcode is known but does not have valid operands.  Print out the
   3577   1.1  christos      syntax for this opcode.  */
   3578   1.1  christos   if (opcode == 0)
   3579   1.1  christos     {
   3580   1.1  christos       if (flag_print_insn_syntax)
   3581   1.1  christos 	print_insn_format (name);
   3582   1.1  christos 
   3583   1.1  christos       if (((strcmp (name, "movb") == 0) || (strcmp (name, "movw") == 0))
   3584   1.1  christos 	  && (current_architecture & cpu9s12x))
   3585   1.1  christos 	{
   3586   1.1  christos 	  char *f;
   3587   1.1  christos 	  int movb;
   3588   1.1  christos 	  if (strcmp (name, "movb") == 0)
   3589   1.1  christos 	    movb = 8;
   3590   1.1  christos 	  else
   3591   1.1  christos 	    movb = 0;
   3592   1.1  christos 
   3593   1.1  christos 	  /* The existing operand extract code fell over if these additional modes
   3594   1.1  christos 	     were enabled in m68hc11-opc.c. So they are commented there and
   3595   1.1  christos 	     decoded here instead.  */
   3596   1.1  christos 
   3597   1.1  christos 	  if (operands[1].mode & (M6812_OP_IDX | M6812_OP_IDX_1
   3598   1.1  christos 				  | M6812_OP_IDX_2 | M6812_OP_D_IDX | M6812_OP_D_IDX_2 | M6812_PRE_INC
   3599   1.1  christos 				  | M6812_PRE_DEC | M6812_POST_INC | M6812_POST_DEC ))
   3600   1.1  christos 	    {
   3601   1.1  christos 	      /* first check if valid mode then start building it up */
   3602   1.1  christos 	      if (operands[0].mode & (M6811_OP_IMM8 | M6811_OP_IMM16
   3603   1.1  christos 				      | M6811_OP_IND16 | M6812_OP_IDX | M6812_OP_IDX_1
   3604   1.1  christos 				      | M6812_OP_IDX_2 | M6812_OP_D_IDX | M6812_OP_D_IDX_2))
   3605   1.1  christos 		{
   3606   1.1  christos 		  int opr16a;
   3607   1.1  christos 		  if (operands[1].mode & (M6811_OP_IND16))
   3608   1.1  christos 		    opr16a = 3;
   3609   1.1  christos 		  else
   3610   1.1  christos 		    opr16a = 0;
   3611   1.1  christos 
   3612   1.1  christos 		  f = m68hc11_new_insn (2);
   3613   1.1  christos 
   3614   1.1  christos 		  if (operands[0].mode & (M6811_OP_IMM8 | M6811_OP_IMM16))
   3615   1.1  christos 		    {
   3616   1.1  christos 		      number_to_chars_bigendian (f, 0x1800 + movb + opr16a, 2);
   3617   1.1  christos 		      build_indexed_byte (&operands[1], operands[1].mode, 1);
   3618   1.1  christos 		      if (movb)
   3619   1.1  christos 			fixup8 (&operands[0].exp, M6811_OP_IMM8,
   3620   1.1  christos 				operands[0].mode);
   3621   1.1  christos 		      else
   3622   1.1  christos 			fixup16 (&operands[0].exp, M6811_OP_IMM16,
   3623   1.1  christos 				 operands[0].mode);
   3624   1.1  christos 
   3625   1.1  christos 		      return;
   3626   1.1  christos 		    }
   3627   1.1  christos 		  else if (operands[0].mode & M6811_OP_IND16)
   3628   1.1  christos 		    {
   3629   1.1  christos 		      number_to_chars_bigendian (f, 0x1801 + movb + opr16a, 2);
   3630   1.1  christos 		      build_indexed_byte (&operands[1], operands[1].mode, 1);
   3631   1.1  christos 		      fixup16 (&operands[0].exp, M6811_OP_IND16, operands[0].mode);
   3632   1.1  christos 		      return;
   3633   1.1  christos 		    }
   3634   1.1  christos 		  else
   3635   1.1  christos 		    {
   3636   1.1  christos 		      number_to_chars_bigendian (f, 0x1802 + movb + opr16a, 2);
   3637   1.1  christos 		      build_indexed_byte (&operands[0], operands[0].mode, 1);
   3638   1.1  christos 		      build_indexed_byte (&operands[1], operands[1].mode, 1);
   3639   1.1  christos 		      return;
   3640   1.1  christos 		    }
   3641   1.1  christos 		}
   3642   1.1  christos 	    }
   3643   1.1  christos 	  else if (operands[1].mode & M6811_OP_IND16)
   3644   1.1  christos 	    {
   3645   1.1  christos 	      /* First check if this is valid mode, then start building it up. */
   3646   1.1  christos 	      if (operands[0].mode & (M6811_OP_IMM8 | M6811_OP_IMM16
   3647   1.1  christos 				      | M6811_OP_IND16 | M6812_OP_IDX | M6812_OP_IDX_1
   3648   1.1  christos 				      | M6812_OP_IDX_2 | M6812_OP_D_IDX | M6812_OP_D_IDX_2))
   3649   1.1  christos 		{
   3650   1.1  christos 		  int opr16a;
   3651   1.1  christos 		  if (operands[1].mode & (M6811_OP_IND16))
   3652   1.1  christos 		    opr16a = 3;
   3653   1.1  christos 		  else
   3654   1.1  christos 		    opr16a = 0;
   3655   1.1  christos 
   3656   1.1  christos 		  f = m68hc11_new_insn (2);
   3657   1.1  christos 
   3658   1.1  christos 		  /* The first two cases here should actually be covered by the
   3659   1.1  christos 		     normal operand code. */
   3660   1.1  christos 		  if (operands[0].mode & (M6811_OP_IMM8 | M6811_OP_IMM16))
   3661   1.1  christos 		    {
   3662   1.1  christos 		      number_to_chars_bigendian (f, 0x1800 + movb + opr16a, 2);
   3663   1.1  christos 		      if (movb)
   3664   1.1  christos 			fixup8 (&operands[0].exp, M6811_OP_IMM8, operands[0].mode);
   3665   1.1  christos 		      else
   3666   1.1  christos 			fixup16 (&operands[0].exp, M6811_OP_IMM16, operands[0].mode);
   3667   1.1  christos 
   3668   1.1  christos 		      fixup16 (&operands[0].exp, M6811_OP_IND16, operands[0].mode);
   3669   1.1  christos 		      return;
   3670   1.1  christos 		    }
   3671   1.1  christos 		  else if (operands[0].mode & M6811_OP_IND16)
   3672   1.1  christos 		    {
   3673   1.1  christos 		      number_to_chars_bigendian (f, 0x1801 + movb + opr16a, 2);
   3674   1.1  christos 		      build_indexed_byte (&operands[1], operands[1].mode, 1);
   3675   1.1  christos 		      fixup16 (&operands[0].exp, M6811_OP_IND16, operands[0].mode);
   3676   1.1  christos 		      return;
   3677   1.1  christos 		    }
   3678   1.1  christos 		  else
   3679   1.1  christos 		    {
   3680   1.1  christos 		      number_to_chars_bigendian (f, 0x1802 + movb + opr16a, 2);
   3681   1.1  christos 		      build_indexed_byte (&operands[0], operands[0].mode, 1);
   3682   1.1  christos 		      fixup16 (&operands[1].exp, M6811_OP_IND16, operands[1].mode);
   3683   1.1  christos 		      return;
   3684   1.1  christos 		    }
   3685   1.1  christos 		}
   3686   1.1  christos 	    }
   3687   1.1  christos 
   3688   1.1  christos 	  as_bad (_("Invalid operand for `%s'"), name);
   3689   1.1  christos 	  return;
   3690   1.1  christos 
   3691   1.1  christos 	}
   3692   1.1  christos       else
   3693   1.1  christos 	{
   3694   1.1  christos 	  as_bad (_("Invalid operand for `%s'"), name);
   3695   1.1  christos 	  return;
   3696   1.1  christos 	}
   3697   1.1  christos     }
   3698   1.1  christos 
   3699   1.1  christos   /* Treat dbeq/ibeq/tbeq instructions in a special way.  The branch is
   3700   1.1  christos      relative and must be in the range -256..255 (9-bits).  */
   3701   1.1  christos   if ((opcode->format & M6812_XBCC_MARKER)
   3702   1.1  christos       && (opcode->format & M6811_OP_JUMP_REL))
   3703   1.1  christos     build_dbranch_insn (opcode, operands, nb_operands, branch_optimize);
   3704   1.1  christos 
   3705   1.1  christos   /* Relative jumps instructions are taken care of separately.  We have to make
   3706   1.1  christos      sure that the relative branch is within the range -128..127.  If it's out
   3707   1.1  christos      of range, the instructions are changed into absolute instructions.
   3708   1.1  christos      This is not supported for the brset and brclr instructions.  */
   3709   1.1  christos   else if ((opcode->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
   3710   1.1  christos 	   && !(opcode->format & M6811_OP_BITMASK))
   3711   1.1  christos     build_jump_insn (opcode, operands, nb_operands, branch_optimize);
   3712   1.1  christos   else
   3713   1.1  christos     build_insn (opcode, operands, nb_operands);
   3714   1.1  christos }
   3715  1.10  christos 
   3716   1.1  christos 
   3717   1.1  christos /* Pseudo op to control the ELF flags.  */
   3719   1.1  christos static void
   3720   1.1  christos s_m68hc11_mode (int x ATTRIBUTE_UNUSED)
   3721   1.1  christos {
   3722   1.1  christos   char *name = input_line_pointer, ch;
   3723   1.1  christos 
   3724   1.1  christos   while (!is_end_of_stmt (*input_line_pointer))
   3725   1.1  christos     input_line_pointer++;
   3726   1.1  christos   ch = *input_line_pointer;
   3727   1.1  christos   *input_line_pointer = '\0';
   3728   1.1  christos 
   3729   1.1  christos   if (strcmp (name, "mshort") == 0)
   3730   1.1  christos     {
   3731   1.1  christos       elf_flags &= ~E_M68HC11_I32;
   3732   1.1  christos     }
   3733   1.1  christos   else if (strcmp (name, "mlong") == 0)
   3734   1.1  christos     {
   3735   1.1  christos       elf_flags |= E_M68HC11_I32;
   3736   1.1  christos     }
   3737   1.1  christos   else if (strcmp (name, "mshort-double") == 0)
   3738   1.1  christos     {
   3739   1.1  christos       elf_flags &= ~E_M68HC11_F64;
   3740   1.1  christos     }
   3741   1.1  christos   else if (strcmp (name, "mlong-double") == 0)
   3742   1.1  christos     {
   3743   1.1  christos       elf_flags |= E_M68HC11_F64;
   3744   1.1  christos     }
   3745   1.1  christos   else
   3746   1.1  christos     {
   3747   1.1  christos       as_warn (_("Invalid mode: %s\n"), name);
   3748   1.1  christos     }
   3749   1.1  christos   *input_line_pointer = ch;
   3750   1.1  christos   demand_empty_rest_of_line ();
   3751   1.1  christos }
   3752   1.1  christos 
   3753   1.1  christos /* Mark the symbols with STO_M68HC12_FAR to indicate the functions
   3754   1.1  christos    are using 'rtc' for returning.  It is necessary to use 'call'
   3755   1.1  christos    to invoke them.  This is also used by the debugger to correctly
   3756   1.1  christos    find the stack frame.  */
   3757   1.1  christos static void
   3758   1.1  christos s_m68hc11_mark_symbol (int mark)
   3759   1.3  christos {
   3760   1.1  christos   char *name;
   3761   1.3  christos   int c;
   3762   1.1  christos   symbolS *symbolP;
   3763   1.1  christos   asymbol *bfdsym;
   3764   1.1  christos   elf_symbol_type *elfsym;
   3765   1.1  christos 
   3766   1.8  christos   do
   3767   1.1  christos     {
   3768   1.1  christos       c = get_symbol_name (&name);
   3769   1.1  christos       symbolP = symbol_find_or_make (name);
   3770   1.1  christos       (void) restore_line_pointer (c);
   3771   1.1  christos 
   3772   1.1  christos       SKIP_WHITESPACE ();
   3773   1.1  christos 
   3774   1.1  christos       bfdsym = symbol_get_bfdsym (symbolP);
   3775   1.1  christos       elfsym = elf_symbol_from (bfdsym);
   3776   1.1  christos 
   3777   1.1  christos       gas_assert (elfsym);
   3778   1.1  christos 
   3779   1.1  christos       /* Mark the symbol far (using rtc for function return).  */
   3780   1.1  christos       elfsym->internal_elf_sym.st_other |= mark;
   3781   1.1  christos 
   3782   1.1  christos       if (c == ',')
   3783   1.1  christos 	{
   3784   1.1  christos 	  input_line_pointer ++;
   3785   1.1  christos 
   3786   1.1  christos 	  SKIP_WHITESPACE ();
   3787   1.1  christos 
   3788   1.1  christos 	  if (*input_line_pointer == '\n')
   3789   1.1  christos 	    c = '\n';
   3790   1.1  christos 	}
   3791   1.1  christos     }
   3792   1.1  christos   while (c == ',');
   3793   1.1  christos 
   3794   1.1  christos   demand_empty_rest_of_line ();
   3795   1.1  christos }
   3796   1.1  christos 
   3797   1.1  christos static void
   3798   1.1  christos s_m68hc11_relax (int ignore ATTRIBUTE_UNUSED)
   3799   1.1  christos {
   3800   1.1  christos   expressionS ex;
   3801   1.1  christos 
   3802   1.1  christos   expression (&ex);
   3803   1.1  christos 
   3804   1.1  christos   if (ex.X_op != O_symbol || ex.X_add_number != 0)
   3805   1.1  christos     {
   3806   1.1  christos       as_bad (_("bad .relax format"));
   3807   1.1  christos       ignore_rest_of_line ();
   3808   1.1  christos       return;
   3809   1.1  christos     }
   3810   1.1  christos 
   3811   1.1  christos   fix_new_exp (frag_now, frag_now_fix (), 0, &ex, 1,
   3812   1.1  christos                BFD_RELOC_M68HC11_RL_GROUP);
   3813   1.1  christos 
   3814   1.1  christos   demand_empty_rest_of_line ();
   3815   1.1  christos }
   3816   1.1  christos 
   3817   1.1  christos 
   3818   1.1  christos /* Relocation, relaxation and frag conversions.  */
   3820   1.1  christos 
   3821   1.1  christos /* PC-relative offsets are relative to the start of the
   3822   1.1  christos    next instruction.  That is, the address of the offset, plus its
   3823   1.1  christos    size, since the offset is always the last part of the insn.  */
   3824   1.1  christos long
   3825   1.1  christos md_pcrel_from (fixS *fixP)
   3826   1.1  christos {
   3827   1.1  christos   if (fixP->fx_r_type == BFD_RELOC_M68HC11_RL_JUMP)
   3828   1.1  christos     return 0;
   3829   1.1  christos 
   3830  1.10  christos   return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
   3831  1.10  christos }
   3832   1.1  christos 
   3833   1.1  christos /* If while processing a fixup, a reloc really needs to be created
   3834   1.1  christos    then it is done here.  */
   3835   1.1  christos arelent *
   3836   1.1  christos tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
   3837   1.1  christos {
   3838  1.10  christos   arelent *reloc;
   3839   1.1  christos 
   3840   1.1  christos   reloc = notes_alloc (sizeof (arelent));
   3841   1.1  christos   reloc->sym_ptr_ptr = notes_alloc (sizeof (asymbol *));
   3842   1.1  christos   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
   3843   1.1  christos   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
   3844   1.1  christos   if (fixp->fx_r_type == 0)
   3845   1.1  christos     reloc->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_16);
   3846   1.1  christos   else
   3847   1.1  christos     reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
   3848   1.1  christos   if (reloc->howto == NULL)
   3849   1.1  christos     {
   3850   1.1  christos       as_bad_where (fixp->fx_file, fixp->fx_line,
   3851   1.1  christos 		    _("Relocation %d is not supported by object file format."),
   3852   1.1  christos 		    (int) fixp->fx_r_type);
   3853   1.1  christos       return NULL;
   3854   1.1  christos     }
   3855   1.1  christos 
   3856   1.1  christos   /* Since we use Rel instead of Rela, encode the vtable entry to be
   3857   1.1  christos      used in the relocation's section offset.  */
   3858   1.1  christos   if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
   3859   1.1  christos     reloc->address = fixp->fx_offset;
   3860   1.1  christos 
   3861   1.1  christos   reloc->addend = 0;
   3862   1.1  christos   return reloc;
   3863   1.1  christos }
   3864   1.1  christos 
   3865   1.1  christos /* We need a port-specific relaxation function to cope with sym2 - sym1
   3866   1.1  christos    relative expressions with both symbols in the same segment (but not
   3867   1.1  christos    necessarily in the same frag as this insn), for example:
   3868   1.1  christos      ldab sym2-(sym1-2),pc
   3869   1.1  christos     sym1:
   3870   1.1  christos    The offset can be 5, 9 or 16 bits long.  */
   3871   1.1  christos 
   3872   1.1  christos long
   3873   1.1  christos m68hc11_relax_frag (segT seg ATTRIBUTE_UNUSED, fragS *fragP,
   3874   1.1  christos                     long stretch ATTRIBUTE_UNUSED)
   3875   1.1  christos {
   3876   1.6  christos   long growth;
   3877   1.1  christos   offsetT aim = 0;
   3878   1.1  christos   symbolS *symbolP;
   3879   1.1  christos   const relax_typeS *this_type;
   3880   1.1  christos   const relax_typeS *start_type;
   3881   1.1  christos   relax_substateT next_state;
   3882   1.1  christos   relax_substateT this_state;
   3883   1.1  christos   const relax_typeS *table = TC_GENERIC_RELAX_TABLE;
   3884   1.1  christos 
   3885   1.1  christos   /* We only have to cope with frags as prepared by
   3886   1.1  christos      md_estimate_size_before_relax.  The STATE_BITS16 case may get here
   3887   1.1  christos      because of the different reasons that it's not relaxable.  */
   3888   1.1  christos   switch (fragP->fr_subtype)
   3889   1.1  christos     {
   3890   1.1  christos     case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS16):
   3891   1.1  christos     case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16):
   3892   1.9  christos       /* When we get to this state, the frag won't grow any more.  */
   3893   1.1  christos       return 0;
   3894   1.1  christos 
   3895   1.1  christos     case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS5):
   3896   1.9  christos     case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS5):
   3897   1.1  christos     case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS9):
   3898   1.1  christos     case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9):
   3899   1.1  christos       if (fragP->fr_symbol == NULL
   3900   1.1  christos 	  || S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
   3901   1.1  christos 	as_fatal (_("internal inconsistency problem in %s: fr_symbol %lx"),
   3902   1.9  christos 		  __func__, (long) fragP->fr_symbol);
   3903   1.1  christos       symbolP = fragP->fr_symbol;
   3904   1.1  christos       if (symbol_resolved_p (symbolP))
   3905   1.1  christos 	as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
   3906   1.1  christos 		  __func__);
   3907   1.1  christos       aim = S_GET_VALUE (symbolP);
   3908   1.1  christos       break;
   3909   1.1  christos 
   3910   1.1  christos     default:
   3911   1.1  christos       as_fatal (_("internal inconsistency problem in %s: fr_subtype %d"),
   3912   1.1  christos 		  __func__, fragP->fr_subtype);
   3913   1.1  christos     }
   3914   1.1  christos 
   3915   1.1  christos   /* The rest is stolen from relax_frag.  There's no obvious way to
   3916   1.1  christos      share the code, but fortunately no requirement to keep in sync as
   3917   1.1  christos      long as fragP->fr_symbol does not have its segment changed.  */
   3918   1.1  christos 
   3919   1.1  christos   this_state = fragP->fr_subtype;
   3920   1.1  christos   start_type = this_type = table + this_state;
   3921   1.1  christos 
   3922   1.1  christos   if (aim < 0)
   3923   1.1  christos     {
   3924   1.1  christos       /* Look backwards.  */
   3925   1.1  christos       for (next_state = this_type->rlx_more; next_state;)
   3926   1.1  christos 	if (aim >= this_type->rlx_backward)
   3927   1.1  christos 	  next_state = 0;
   3928   1.1  christos 	else
   3929   1.1  christos 	  {
   3930   1.1  christos 	    /* Grow to next state.  */
   3931   1.1  christos 	    this_state = next_state;
   3932   1.1  christos 	    this_type = table + this_state;
   3933   1.1  christos 	    next_state = this_type->rlx_more;
   3934   1.1  christos 	  }
   3935   1.1  christos     }
   3936   1.1  christos   else
   3937   1.1  christos     {
   3938   1.1  christos       /* Look forwards.  */
   3939   1.1  christos       for (next_state = this_type->rlx_more; next_state;)
   3940   1.1  christos 	if (aim <= this_type->rlx_forward)
   3941   1.1  christos 	  next_state = 0;
   3942   1.1  christos 	else
   3943   1.1  christos 	  {
   3944   1.1  christos 	    /* Grow to next state.  */
   3945   1.1  christos 	    this_state = next_state;
   3946   1.1  christos 	    this_type = table + this_state;
   3947   1.1  christos 	    next_state = this_type->rlx_more;
   3948   1.1  christos 	  }
   3949   1.1  christos     }
   3950   1.1  christos 
   3951   1.1  christos   growth = this_type->rlx_length - start_type->rlx_length;
   3952   1.1  christos   if (growth != 0)
   3953   1.1  christos     fragP->fr_subtype = this_state;
   3954   1.1  christos   return growth;
   3955   1.1  christos }
   3956   1.3  christos 
   3957   1.1  christos void
   3958   1.1  christos md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, asection *sec ATTRIBUTE_UNUSED,
   3959   1.1  christos                  fragS *fragP)
   3960   1.1  christos {
   3961   1.1  christos   long value;
   3962   1.1  christos   long disp;
   3963   1.1  christos   char *buffer_address = fragP->fr_literal;
   3964   1.1  christos 
   3965   1.1  christos   /* Address in object code of the displacement.  */
   3966   1.1  christos   int object_address = fragP->fr_fix + fragP->fr_address;
   3967   1.1  christos 
   3968   1.1  christos   buffer_address += fragP->fr_fix;
   3969   1.1  christos 
   3970   1.1  christos   /* The displacement of the address, from current location.  */
   3971   1.1  christos   value = S_GET_VALUE (fragP->fr_symbol);
   3972   1.1  christos   disp = (value + fragP->fr_offset) - object_address;
   3973   1.1  christos 
   3974   1.1  christos   switch (fragP->fr_subtype)
   3975   1.1  christos     {
   3976   1.1  christos     case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE):
   3977   1.1  christos       fragP->fr_opcode[1] = disp;
   3978   1.1  christos       break;
   3979   1.1  christos 
   3980   1.1  christos     case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD):
   3981   1.1  christos       /* This relax is only for bsr and bra.  */
   3982   1.1  christos       gas_assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
   3983   1.1  christos 	      || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
   3984   1.1  christos 	      || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
   3985   1.1  christos 
   3986   1.1  christos       fragP->fr_opcode[0] = convert_branch (fragP->fr_opcode[0]);
   3987   1.1  christos 
   3988   1.1  christos       fix_new (fragP, fragP->fr_fix - 1, 2,
   3989   1.1  christos 	       fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
   3990   1.1  christos       fragP->fr_fix += 1;
   3991   1.1  christos       break;
   3992   1.1  christos 
   3993   1.1  christos     case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_BYTE):
   3994   1.1  christos     case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_BYTE):
   3995   1.1  christos       fragP->fr_opcode[1] = disp;
   3996   1.1  christos       break;
   3997   1.1  christos 
   3998   1.1  christos     case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_WORD):
   3999   1.1  christos       /* Invert branch.  */
   4000   1.1  christos       fragP->fr_opcode[0] ^= 1;
   4001   1.1  christos       fragP->fr_opcode[1] = 3;	/* Branch offset.  */
   4002   1.1  christos       buffer_address[0] = M6811_JMP;
   4003   1.3  christos       fix_new (fragP, fragP->fr_fix + 1, 2,
   4004   1.3  christos 	       fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
   4005   1.1  christos       fragP->fr_fix += 3;
   4006   1.1  christos       break;
   4007   1.1  christos 
   4008   1.1  christos     case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_WORD):
   4009   1.1  christos       /* Translate branch into a long branch.  */
   4010   1.1  christos       fragP->fr_opcode[1] = fragP->fr_opcode[0];
   4011   1.1  christos       fragP->fr_opcode[0] = M6811_OPCODE_PAGE2;
   4012   1.1  christos 
   4013   1.1  christos       fix_new (fragP, fragP->fr_fix, 2,
   4014   1.1  christos 	       fragP->fr_symbol, fragP->fr_offset, 1,
   4015   1.1  christos 		      BFD_RELOC_16_PCREL);
   4016   1.1  christos       fragP->fr_fix += 2;
   4017   1.1  christos       break;
   4018   1.1  christos 
   4019   1.1  christos     case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS5):
   4020   1.1  christos       if (fragP->fr_symbol != 0
   4021   1.1  christos           && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
   4022   1.1  christos         value = disp;
   4023   1.1  christos       /* fall through  */
   4024   1.1  christos 
   4025   1.1  christos     case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS5):
   4026   1.1  christos       fragP->fr_opcode[0] = fragP->fr_opcode[0] << 6;
   4027   1.1  christos       fragP->fr_opcode[0] |= value & 0x1f;
   4028   1.1  christos       break;
   4029   1.1  christos 
   4030   1.1  christos     case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS9):
   4031   1.1  christos       /* For a PC-relative offset, use the displacement with a -1 correction
   4032   1.1  christos          to take into account the additional byte of the insn.  */
   4033   1.1  christos       if (fragP->fr_symbol != 0
   4034   1.1  christos           && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
   4035   1.1  christos         value = disp - 1;
   4036   1.1  christos       /* fall through  */
   4037   1.1  christos 
   4038   1.1  christos     case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9):
   4039   1.1  christos       fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3);
   4040   1.1  christos       fragP->fr_opcode[0] |= 0xE0;
   4041   1.1  christos       fragP->fr_opcode[0] |= (value >> 8) & 1;
   4042   1.1  christos       fragP->fr_opcode[1] = value;
   4043   1.1  christos       fragP->fr_fix += 1;
   4044   1.3  christos       break;
   4045   1.3  christos 
   4046   1.3  christos     case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS16):
   4047   1.1  christos     case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16):
   4048   1.1  christos       fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3);
   4049   1.1  christos       fragP->fr_opcode[0] |= 0xe2;
   4050   1.1  christos       if ((fragP->fr_opcode[0] & 0x0ff) == 0x0fa
   4051   1.1  christos           && fragP->fr_symbol != 0
   4052   1.1  christos           && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
   4053   1.1  christos 	{
   4054   1.1  christos 	  fix_new (fragP, fragP->fr_fix, 2,
   4055   1.1  christos 	           fragP->fr_symbol, fragP->fr_offset,
   4056   1.1  christos 		   1, BFD_RELOC_16_PCREL);
   4057   1.1  christos 	}
   4058   1.1  christos       else
   4059   1.1  christos 	{
   4060   1.1  christos 	  fix_new (fragP, fragP->fr_fix, 2,
   4061   1.1  christos 		   fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
   4062   1.1  christos 	}
   4063   1.1  christos       fragP->fr_fix += 2;
   4064   1.1  christos       break;
   4065   1.1  christos 
   4066   1.1  christos     case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_BYTE):
   4067   1.1  christos       if (disp < 0)
   4068   1.1  christos 	fragP->fr_opcode[0] |= 0x10;
   4069   1.1  christos 
   4070   1.1  christos       fragP->fr_opcode[1] = disp & 0x0FF;
   4071   1.1  christos       break;
   4072   1.1  christos 
   4073   1.1  christos     case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_WORD):
   4074   1.1  christos       /* Invert branch.  */
   4075   1.1  christos       fragP->fr_opcode[0] ^= 0x20;
   4076   1.1  christos       fragP->fr_opcode[1] = 3;	/* Branch offset.  */
   4077   1.1  christos       buffer_address[0] = M6812_JMP;
   4078   1.1  christos       fix_new (fragP, fragP->fr_fix + 1, 2,
   4079   1.1  christos 	       fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
   4080   1.1  christos       fragP->fr_fix += 3;
   4081   1.1  christos       break;
   4082   1.1  christos 
   4083   1.1  christos     default:
   4084   1.1  christos       break;
   4085   1.1  christos     }
   4086   1.1  christos }
   4087   1.1  christos 
   4088   1.1  christos /* On an ELF system, we can't relax a weak symbol.  The weak symbol
   4089   1.1  christos    can be overridden at final link time by a non weak symbol.  We can
   4090   1.1  christos    relax externally visible symbol because there is no shared library
   4091   1.1  christos    and such symbol can't be overridden (unless they are weak).  */
   4092   1.1  christos static int
   4093   1.1  christos relaxable_symbol (symbolS *symbol)
   4094   1.1  christos {
   4095   1.1  christos   return ! S_IS_WEAK (symbol);
   4096   1.1  christos }
   4097   1.1  christos 
   4098   1.1  christos /* Force truly undefined symbols to their maximum size, and generally set up
   4099   1.1  christos    the frag list to be relaxed.  */
   4100   1.1  christos int
   4101   1.1  christos md_estimate_size_before_relax (fragS *fragP, asection *segment)
   4102   1.1  christos {
   4103   1.1  christos   if (RELAX_LENGTH (fragP->fr_subtype) == STATE_UNDF)
   4104   1.1  christos     {
   4105   1.1  christos       if (S_GET_SEGMENT (fragP->fr_symbol) != segment
   4106   1.1  christos 	  || !relaxable_symbol (fragP->fr_symbol)
   4107   1.1  christos           || (segment != absolute_section
   4108   1.1  christos               && RELAX_STATE (fragP->fr_subtype) == STATE_INDEXED_OFFSET))
   4109   1.1  christos 	{
   4110   1.1  christos 	  /* Non-relaxable cases.  */
   4111   1.1  christos 	  int old_fr_fix;
   4112   1.1  christos 	  char *buffer_address;
   4113   1.1  christos 
   4114   1.1  christos 	  old_fr_fix = fragP->fr_fix;
   4115   1.1  christos 	  buffer_address = fragP->fr_fix + fragP->fr_literal;
   4116   1.1  christos 
   4117   1.1  christos 	  switch (RELAX_STATE (fragP->fr_subtype))
   4118   1.1  christos 	    {
   4119   1.1  christos 	    case STATE_PC_RELATIVE:
   4120   1.1  christos 
   4121   1.1  christos 	      /* This relax is only for bsr and bra.  */
   4122   1.1  christos 	      gas_assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
   4123   1.1  christos 		      || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
   4124   1.1  christos 		      || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
   4125   1.1  christos 
   4126   1.1  christos 	      if (flag_fixed_branches)
   4127   1.1  christos 		as_bad_where (fragP->fr_file, fragP->fr_line,
   4128   1.1  christos 			      _("bra or bsr with undefined symbol."));
   4129   1.1  christos 
   4130   1.1  christos 	      /* The symbol is undefined or in a separate section.
   4131   1.1  christos 		 Turn bra into a jmp and bsr into a jsr.  The insn
   4132   1.1  christos 		 becomes 3 bytes long (instead of 2).  A fixup is
   4133   1.1  christos 		 necessary for the unresolved symbol address.  */
   4134   1.1  christos 	      fragP->fr_opcode[0] = convert_branch (fragP->fr_opcode[0]);
   4135   1.1  christos 
   4136   1.1  christos 	      fix_new (fragP, fragP->fr_fix - 1, 2, fragP->fr_symbol,
   4137   1.1  christos 		       fragP->fr_offset, 0, BFD_RELOC_16);
   4138   1.1  christos 	      fragP->fr_fix++;
   4139   1.1  christos 	      break;
   4140   1.1  christos 
   4141   1.1  christos 	    case STATE_CONDITIONAL_BRANCH:
   4142   1.1  christos 	      gas_assert (current_architecture & cpu6811);
   4143   1.1  christos 
   4144   1.1  christos 	      fragP->fr_opcode[0] ^= 1;	/* Reverse sense of branch.  */
   4145   1.1  christos 	      fragP->fr_opcode[1] = 3;	/* Skip next jmp insn (3 bytes).  */
   4146   1.1  christos 
   4147   1.1  christos 	      /* Don't use fr_opcode[2] because this may be
   4148   1.1  christos 		 in a different frag.  */
   4149   1.1  christos 	      buffer_address[0] = M6811_JMP;
   4150   1.1  christos 
   4151   1.1  christos 	      fragP->fr_fix++;
   4152   1.1  christos 	      fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
   4153   1.1  christos 		       fragP->fr_offset, 0, BFD_RELOC_16);
   4154   1.1  christos 	      fragP->fr_fix += 2;
   4155   1.1  christos 	      break;
   4156   1.1  christos 
   4157   1.1  christos 	    case STATE_INDEXED_OFFSET:
   4158   1.1  christos 	      gas_assert (current_architecture & cpu6812);
   4159   1.1  christos 
   4160   1.1  christos               if (fragP->fr_symbol
   4161   1.1  christos                   && S_GET_SEGMENT (fragP->fr_symbol) == absolute_section)
   4162   1.1  christos                 {
   4163   1.1  christos                    fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_OFFSET,
   4164   1.1  christos                                                      STATE_BITS5);
   4165   1.1  christos                    /* Return the size of the variable part of the frag. */
   4166   1.1  christos                    return md_relax_table[fragP->fr_subtype].rlx_length;
   4167   1.1  christos                 }
   4168   1.1  christos               else
   4169   1.1  christos                 {
   4170   1.1  christos                    /* Switch the indexed operation to 16-bit mode.  */
   4171   1.1  christos                    fragP->fr_opcode[0] = fragP->fr_opcode[0] << 3;
   4172   1.1  christos                    fragP->fr_opcode[0] |= 0xe2;
   4173   1.1  christos                    fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
   4174   1.1  christos                             fragP->fr_offset, 0, BFD_RELOC_16);
   4175   1.1  christos                    fragP->fr_fix += 2;
   4176   1.1  christos                 }
   4177   1.1  christos 	      break;
   4178   1.1  christos 
   4179   1.1  christos 	    case STATE_INDEXED_PCREL:
   4180   1.1  christos 	      gas_assert (current_architecture & cpu6812);
   4181   1.1  christos 
   4182   1.1  christos               if (fragP->fr_symbol
   4183   1.1  christos                   && S_GET_SEGMENT (fragP->fr_symbol) == absolute_section)
   4184   1.1  christos                 {
   4185   1.1  christos                    fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_PCREL,
   4186   1.1  christos                                                      STATE_BITS5);
   4187   1.1  christos                    /* Return the size of the variable part of the frag. */
   4188   1.1  christos                    return md_relax_table[fragP->fr_subtype].rlx_length;
   4189   1.1  christos                 }
   4190   1.1  christos               else
   4191   1.1  christos                 {
   4192   1.1  christos                    fragP->fr_opcode[0] = fragP->fr_opcode[0] << 3;
   4193   1.1  christos                    fragP->fr_opcode[0] |= 0xe2;
   4194   1.1  christos                    fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
   4195   1.1  christos 			    fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
   4196   1.1  christos                    fragP->fr_fix += 2;
   4197   1.1  christos                 }
   4198   1.1  christos 	      break;
   4199   1.1  christos 
   4200   1.1  christos 	    case STATE_XBCC_BRANCH:
   4201   1.1  christos 	      gas_assert (current_architecture & cpu6812);
   4202   1.1  christos 
   4203   1.1  christos 	      fragP->fr_opcode[0] ^= 0x20;	/* Reverse sense of branch.  */
   4204   1.1  christos 	      fragP->fr_opcode[1] = 3;	/* Skip next jmp insn (3 bytes).  */
   4205   1.1  christos 
   4206   1.1  christos 	      /* Don't use fr_opcode[2] because this may be
   4207   1.1  christos 		 in a different frag.  */
   4208   1.1  christos 	      buffer_address[0] = M6812_JMP;
   4209   1.1  christos 
   4210   1.1  christos 	      fragP->fr_fix++;
   4211   1.1  christos 	      fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
   4212   1.1  christos 		       fragP->fr_offset, 0, BFD_RELOC_16);
   4213   1.1  christos 	      fragP->fr_fix += 2;
   4214   1.1  christos 	      break;
   4215   1.1  christos 
   4216   1.1  christos 	    case STATE_CONDITIONAL_BRANCH_6812:
   4217   1.1  christos 	      gas_assert (current_architecture & cpu6812);
   4218   1.1  christos 
   4219   1.1  christos 	      /* Translate into a lbcc branch.  */
   4220   1.1  christos 	      fragP->fr_opcode[1] = fragP->fr_opcode[0];
   4221   1.1  christos 	      fragP->fr_opcode[0] = M6811_OPCODE_PAGE2;
   4222   1.1  christos 
   4223   1.1  christos 	      fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
   4224   1.1  christos                        fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
   4225   1.1  christos 	      fragP->fr_fix += 2;
   4226   1.1  christos 	      break;
   4227   1.1  christos 
   4228   1.1  christos 	    default:
   4229   1.1  christos 	      as_fatal (_("Subtype %d is not recognized."), fragP->fr_subtype);
   4230   1.1  christos 	    }
   4231   1.1  christos 	  frag_wane (fragP);
   4232   1.1  christos 
   4233   1.1  christos 	  /* Return the growth in the fixed part of the frag.  */
   4234   1.1  christos 	  return fragP->fr_fix - old_fr_fix;
   4235   1.1  christos 	}
   4236   1.1  christos 
   4237   1.1  christos       /* Relaxable cases.  */
   4238   1.1  christos       switch (RELAX_STATE (fragP->fr_subtype))
   4239   1.1  christos 	{
   4240   1.1  christos 	case STATE_PC_RELATIVE:
   4241   1.1  christos 	  /* This relax is only for bsr and bra.  */
   4242   1.1  christos 	  gas_assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
   4243   1.1  christos 		  || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
   4244   1.1  christos 		  || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
   4245   1.1  christos 
   4246   1.1  christos 	  fragP->fr_subtype = ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE);
   4247   1.1  christos 	  break;
   4248   1.1  christos 
   4249   1.1  christos 	case STATE_CONDITIONAL_BRANCH:
   4250   1.1  christos 	  gas_assert (current_architecture & cpu6811);
   4251   1.1  christos 
   4252   1.1  christos 	  fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH,
   4253   1.1  christos 					    STATE_BYTE);
   4254   1.1  christos 	  break;
   4255   1.1  christos 
   4256   1.1  christos 	case STATE_INDEXED_OFFSET:
   4257   1.1  christos 	  gas_assert (current_architecture & cpu6812);
   4258   1.1  christos 
   4259   1.1  christos 	  fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_OFFSET,
   4260   1.1  christos 					    STATE_BITS5);
   4261   1.1  christos 	  break;
   4262   1.1  christos 
   4263   1.1  christos 	case STATE_INDEXED_PCREL:
   4264   1.1  christos 	  gas_assert (current_architecture & cpu6812);
   4265   1.1  christos 
   4266   1.1  christos 	  fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_PCREL,
   4267   1.1  christos 					    STATE_BITS5);
   4268   1.1  christos 	  break;
   4269   1.1  christos 
   4270   1.1  christos 	case STATE_XBCC_BRANCH:
   4271   1.1  christos 	  gas_assert (current_architecture & cpu6812);
   4272   1.1  christos 
   4273   1.1  christos 	  fragP->fr_subtype = ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_BYTE);
   4274   1.1  christos 	  break;
   4275   1.1  christos 
   4276   1.1  christos 	case STATE_CONDITIONAL_BRANCH_6812:
   4277   1.1  christos 	  gas_assert (current_architecture & cpu6812);
   4278   1.1  christos 
   4279   1.1  christos 	  fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812,
   4280   1.1  christos 					    STATE_BYTE);
   4281   1.1  christos 	  break;
   4282   1.1  christos 	}
   4283   1.1  christos     }
   4284   1.1  christos 
   4285   1.1  christos   if (fragP->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))
   4286   1.1  christos     as_fatal (_("Subtype %d is not recognized."), fragP->fr_subtype);
   4287   1.1  christos 
   4288   1.1  christos   /* Return the size of the variable part of the frag.  */
   4289   1.1  christos   return md_relax_table[fragP->fr_subtype].rlx_length;
   4290   1.1  christos }
   4291   1.1  christos 
   4292   1.1  christos /* See whether we need to force a relocation into the output file.  */
   4293   1.1  christos int
   4294   1.1  christos tc_m68hc11_force_relocation (fixS *fixP)
   4295   1.1  christos {
   4296   1.1  christos   if (fixP->fx_r_type == BFD_RELOC_M68HC11_RL_GROUP)
   4297   1.1  christos     return 1;
   4298   1.1  christos 
   4299   1.1  christos   return generic_force_reloc (fixP);
   4300   1.1  christos }
   4301   1.1  christos 
   4302   1.1  christos /* Here we decide which fixups can be adjusted to make them relative
   4303   1.1  christos    to the beginning of the section instead of the symbol.  Basically
   4304   1.1  christos    we need to make sure that the linker relaxation is done
   4305   1.1  christos    correctly, so in some cases we force the original symbol to be
   4306   1.1  christos    used.  */
   4307   1.1  christos int
   4308   1.1  christos tc_m68hc11_fix_adjustable (fixS *fixP)
   4309   1.1  christos {
   4310   1.1  christos   switch (fixP->fx_r_type)
   4311   1.1  christos     {
   4312   1.1  christos       /* For the linker relaxation to work correctly, these relocs
   4313   1.1  christos          need to be on the symbol itself.  */
   4314   1.1  christos     case BFD_RELOC_16:
   4315   1.1  christos     case BFD_RELOC_M68HC11_RL_JUMP:
   4316   1.1  christos     case BFD_RELOC_M68HC11_RL_GROUP:
   4317   1.1  christos     case BFD_RELOC_VTABLE_INHERIT:
   4318   1.1  christos     case BFD_RELOC_VTABLE_ENTRY:
   4319   1.1  christos     case BFD_RELOC_32:
   4320   1.1  christos 
   4321   1.1  christos       /* The memory bank addressing translation also needs the original
   4322   1.1  christos          symbol.  */
   4323   1.1  christos     case BFD_RELOC_M68HC11_LO16:
   4324   1.1  christos     case BFD_RELOC_M68HC11_PAGE:
   4325   1.1  christos     case BFD_RELOC_M68HC11_24:
   4326   1.1  christos       return 0;
   4327   1.1  christos 
   4328   1.1  christos     default:
   4329  1.10  christos       return 1;
   4330   1.1  christos     }
   4331   1.1  christos }
   4332   1.1  christos 
   4333  1.10  christos void
   4334   1.8  christos md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
   4335   1.1  christos {
   4336   1.1  christos   char *where;
   4337   1.1  christos   long value = * valP;
   4338   1.1  christos 
   4339   1.1  christos   if (fixP->fx_addsy == NULL)
   4340   1.1  christos     fixP->fx_done = 1;
   4341   1.1  christos 
   4342   1.1  christos   /* We don't actually support subtracting a symbol.  */
   4343   1.1  christos   if (fixP->fx_subsy != NULL)
   4344   1.1  christos     as_bad_subtract (fixP);
   4345   1.1  christos 
   4346   1.1  christos   /* Patch the instruction with the resolved operand.  Elf relocation
   4347   1.1  christos      info will also be generated to take care of linker/loader fixups.
   4348   1.1  christos      The 68HC11 addresses only 64Kb, we are only concerned by 8 and 16-bit
   4349   1.1  christos      relocs.  BFD_RELOC_8 is basically used for .page0 access (the linker
   4350  1.10  christos      will warn for overflows).  BFD_RELOC_8_PCREL should not be generated
   4351   1.1  christos      because it's either resolved or turned out into non-relative insns (see
   4352   1.1  christos      relax table, bcc, bra, bsr transformations)
   4353   1.1  christos 
   4354   1.1  christos      The BFD_RELOC_32 is necessary for the support of --gstabs.  */
   4355  1.10  christos   where = fixP->fx_frag->fr_literal + fixP->fx_where;
   4356  1.10  christos 
   4357   1.1  christos   switch (fixP->fx_r_type)
   4358   1.1  christos     {
   4359   1.1  christos     case BFD_RELOC_32:
   4360   1.1  christos       bfd_putb32 (value, where);
   4361   1.1  christos       break;
   4362  1.10  christos 
   4363   1.1  christos     case BFD_RELOC_24:
   4364   1.1  christos     case BFD_RELOC_M68HC11_24:
   4365   1.1  christos       bfd_putb16 (value & 0x0ffff, where);
   4366   1.1  christos       where[2] = (value >> 16) & 0xff;
   4367   1.1  christos       break;
   4368   1.1  christos 
   4369   1.1  christos     case BFD_RELOC_16:
   4370   1.1  christos     case BFD_RELOC_16_PCREL:
   4371   1.1  christos     case BFD_RELOC_M68HC11_LO16:
   4372   1.1  christos       bfd_putb16 (value, where);
   4373   1.1  christos       if (value < -65537 || value > 65535)
   4374   1.1  christos 	as_bad_where (fixP->fx_file, fixP->fx_line,
   4375   1.1  christos 		      _("Value out of 16-bit range."));
   4376   1.1  christos       break;
   4377   1.1  christos 
   4378   1.1  christos     case BFD_RELOC_M68HC11_HI8:
   4379  1.10  christos         /* Caution, %hi(<symbol>+%ld) will generate incorrect code if %lo
   4380   1.1  christos           causes a carry. */
   4381   1.1  christos     case BFD_RELOC_M68HC12_HI8XG:
   4382   1.1  christos       value = value >> 8;
   4383  1.10  christos       /* Fall through.  */
   4384   1.1  christos 
   4385   1.1  christos     case BFD_RELOC_M68HC12_LO8XG:
   4386   1.1  christos     case BFD_RELOC_M68HC11_LO8:
   4387   1.1  christos     case BFD_RELOC_8:
   4388   1.1  christos     case BFD_RELOC_M68HC11_PAGE:
   4389   1.1  christos       where[0] = value & 0xff;
   4390   1.1  christos       break;
   4391   1.1  christos 
   4392   1.1  christos     case BFD_RELOC_8_PCREL:
   4393  1.10  christos       where[0] = value & 0xff;
   4394  1.10  christos 
   4395   1.1  christos       if (value < -128 || value > 127)
   4396   1.1  christos 	as_bad_where (fixP->fx_file, fixP->fx_line,
   4397   1.1  christos 		      _("Value %ld too large for 8-bit PC-relative branch."),
   4398   1.1  christos 		      value);
   4399   1.1  christos       break;
   4400   1.1  christos 
   4401   1.1  christos     /* These next two are for XGATE. */
   4402  1.10  christos     case BFD_RELOC_M68HC12_9_PCREL:
   4403  1.10  christos      where[0] |= (value >> 9) & 0x01;
   4404   1.1  christos      where[1] = (value >> 1) & 0xff;
   4405   1.1  christos       if (value < -512 || value > 511)
   4406   1.1  christos         as_bad_where (fixP->fx_file, fixP->fx_line,
   4407   1.1  christos 		      _("Value %ld too large for 9-bit PC-relative branch."),
   4408   1.1  christos 		      value);
   4409   1.1  christos       break;
   4410   1.1  christos 
   4411   1.1  christos     case BFD_RELOC_M68HC12_10_PCREL:
   4412   1.1  christos      where[0] |= (value >> 9) & 0x03;
   4413   1.1  christos      where[1] = (value>> 1) & 0xff;
   4414   1.1  christos       if (value < -1024 || value > 1023)
   4415   1.1  christos         as_bad_where (fixP->fx_file, fixP->fx_line,
   4416   1.1  christos 		      _("Value %ld too large for 10-bit PC-relative branch."),
   4417   1.1  christos 		      value);
   4418   1.1  christos 
   4419   1.1  christos       break;
   4420   1.1  christos 
   4421   1.1  christos     case BFD_RELOC_M68HC11_3B:
   4422   1.1  christos       if (value <= 0 || value > 8)
   4423   1.1  christos 	as_bad_where (fixP->fx_file, fixP->fx_line,
   4424   1.1  christos 		      _("Auto increment/decrement offset '%ld' is out of range."),
   4425   1.1  christos 		      value);
   4426   1.1  christos       if (where[0] & 0x8)
   4427   1.1  christos 	value = 8 - value;
   4428   1.1  christos       else
   4429   1.1  christos 	value--;
   4430   1.1  christos 
   4431   1.3  christos       where[0] = where[0] | (value & 0x07);
   4432   1.1  christos       break;
   4433   1.1  christos 
   4434   1.1  christos     case BFD_RELOC_M68HC12_5B:
   4435   1.1  christos       if (value < -16 || value > 15)
   4436   1.1  christos 	as_bad_where (fixP->fx_file, fixP->fx_line,
   4437   1.1  christos 		      _("Offset out of 5-bit range for movw/movb insn: %ld"),
   4438   1.1  christos 		      value);
   4439   1.1  christos       if (value >= 0)
   4440   1.1  christos 	where[0] |= value;
   4441   1.1  christos       else
   4442   1.1  christos 	where[0] |= (0x10 | (16 + value));
   4443   1.3  christos       break;
   4444   1.1  christos 
   4445   1.1  christos     case BFD_RELOC_M68HC12_9B:
   4446   1.1  christos       if (value < -256 || value > 255)
   4447   1.1  christos         as_bad_where (fixP->fx_file, fixP->fx_line,
   4448   1.1  christos 		      _("Offset out of 9-bit range for movw/movb insn: %ld"),
   4449   1.1  christos 		      value);
   4450   1.1  christos         /* sign bit already in xb postbyte */
   4451   1.1  christos       if (value >= 0)
   4452   1.1  christos         where[1] = value;
   4453   1.1  christos       else
   4454   1.1  christos         where[1] = (256 + value);
   4455   1.1  christos       break;
   4456   1.1  christos 
   4457   1.1  christos     case BFD_RELOC_M68HC12_16B:
   4458   1.1  christos       if (value < -32768 || value > 32767)
   4459   1.1  christos         as_bad_where (fixP->fx_file, fixP->fx_line,
   4460   1.1  christos 		      _("Offset out of 16-bit range for movw/movb insn: %ld"),
   4461   1.1  christos 		      value);
   4462   1.1  christos       if (value < 0)
   4463   1.1  christos         value += 65536;
   4464   1.1  christos 
   4465   1.1  christos       where[0] = (value >> 8);
   4466   1.1  christos       where[1] = (value & 0xff);
   4467   1.1  christos       break;
   4468   1.1  christos 
   4469   1.1  christos     case BFD_RELOC_M68HC11_RL_JUMP:
   4470   1.1  christos     case BFD_RELOC_M68HC11_RL_GROUP:
   4471   1.1  christos     case BFD_RELOC_VTABLE_INHERIT:
   4472   1.1  christos     case BFD_RELOC_VTABLE_ENTRY:
   4473   1.1  christos       fixP->fx_done = 0;
   4474   1.1  christos       return;
   4475   1.1  christos 
   4476   1.1  christos     default:
   4477   1.1  christos       as_fatal (_("Line %d: unknown relocation type: 0x%x."),
   4478   1.1  christos 		fixP->fx_line, fixP->fx_r_type);
   4479   1.1  christos     }
   4480   1.1  christos }
   4481   1.1  christos 
   4482   1.1  christos /* Set the ELF specific flags.  */
   4483   1.1  christos void
   4484   1.1  christos m68hc11_elf_final_processing (void)
   4485   1.1  christos {
   4486   1.1  christos   if (current_architecture & cpu6812s)
   4487   1.1  christos     elf_flags |= EF_M68HCS12_MACH;
   4488   1.1  christos   elf_elfheader (stdoutput)->e_flags &= ~EF_M68HC11_ABI;
   4489   1.1  christos   elf_elfheader (stdoutput)->e_flags |= elf_flags;
   4490   1.1  christos }
   4491   1.1  christos 
   4492   1.1  christos /* Process directives specified via pseudo ops */
   4493   1.1  christos static void
   4494   1.1  christos s_m68hc11_parse_pseudo_instruction (int pseudo_insn)
   4495                 {
   4496                   switch (pseudo_insn)
   4497                     {
   4498                     case E_M68HC11_NO_BANK_WARNING:
   4499                       elf_flags |= E_M68HC11_NO_BANK_WARNING;
   4500                       break;
   4501                     default:
   4502                       as_bad (_("Invalid directive"));
   4503                     }
   4504                 }
   4505