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