ld/
[binutils.git] / gas / config / tc-m68hc11.c
blob822174fa11ea300c556d88cb4e7a90cf85067ab5
1 /* tc-m68hc11.c -- Assembler code for the Motorola 68HC11 & 68HC12.
2 Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
3 Free Software Foundation, Inc.
4 Written by Stephane Carrez (stcarrez@nerim.fr)
6 This file is part of GAS, the GNU Assembler.
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 2, or (at your option)
11 any later version.
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.
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. */
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"
30 const char comment_chars[] = ";!";
31 const char line_comment_chars[] = "#*";
32 const char line_separator_chars[] = "";
34 const char EXP_CHARS[] = "eE";
35 const char FLT_CHARS[] = "dD";
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)
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 */
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)
57 #define IS_OPCODE(C1,C2) (((C1) & 0x0FF) == ((C2) & 0x0FF))
59 /* This table describes how you change sizes for the various types of variable
60 size expressions. This version only supports two kinds. */
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. */
68 relax_typeS md_relax_table[] = {
69 {1, 1, 0, 0}, /* First entries aren't used. */
70 {1, 1, 0, 0}, /* For no good reason except. */
71 {1, 1, 0, 0}, /* that the VAX doesn't either. */
72 {1, 1, 0, 0},
74 /* Relax for bcc <L>.
75 These insns are translated into b!cc +3 jmp L. */
76 {(127), (-128), 0, ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_WORD)},
77 {0, 0, 3, 0},
78 {1, 1, 0, 0},
79 {1, 1, 0, 0},
81 /* Relax for bsr <L> and bra <L>.
82 These insns are translated into jsr and jmp. */
83 {(127), (-128), 0, ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD)},
84 {0, 0, 1, 0},
85 {1, 1, 0, 0},
86 {1, 1, 0, 0},
88 /* Relax for indexed offset: 5-bits, 9-bits, 16-bits. */
89 {(15), (-16), 0, ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9)},
90 {(255), (-256), 1, ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16)},
91 {0, 0, 2, 0},
92 {1, 1, 0, 0},
94 /* Relax for PC relative offset: 5-bits, 9-bits, 16-bits.
95 For the 9-bit case, there will be a -1 correction to take into
96 account the new byte that's why the range is -255..256. */
97 {(15), (-16), 0, ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS9)},
98 {(256), (-255), 1, ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS16)},
99 {0, 0, 2, 0},
100 {1, 1, 0, 0},
102 /* Relax for dbeq/ibeq/tbeq r,<L>:
103 These insns are translated into db!cc +3 jmp L. */
104 {(255), (-256), 0, ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_WORD)},
105 {0, 0, 3, 0},
106 {1, 1, 0, 0},
107 {1, 1, 0, 0},
109 /* Relax for bcc <L> on 68HC12.
110 These insns are translated into lbcc <L>. */
111 {(127), (-128), 0, ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_WORD)},
112 {0, 0, 2, 0},
113 {1, 1, 0, 0},
114 {1, 1, 0, 0},
118 /* 68HC11 and 68HC12 registers. They are numbered according to the 68HC12. */
119 typedef enum register_id {
120 REG_NONE = -1,
121 REG_A = 0,
122 REG_B = 1,
123 REG_CCR = 2,
124 REG_D = 4,
125 REG_X = 5,
126 REG_Y = 6,
127 REG_SP = 7,
128 REG_PC = 8
129 } register_id;
131 typedef struct operand {
132 expressionS exp;
133 register_id reg1;
134 register_id reg2;
135 int mode;
136 } operand;
138 struct m68hc11_opcode_def {
139 long format;
140 int min_operands;
141 int max_operands;
142 int nb_modes;
143 int used;
144 struct m68hc11_opcode *opcode;
147 static struct m68hc11_opcode_def *m68hc11_opcode_defs = 0;
148 static int m68hc11_nb_opcode_defs = 0;
150 typedef struct alias {
151 const char *name;
152 const char *alias;
153 } alias;
155 static alias alias_opcodes[] = {
156 {"cpd", "cmpd"},
157 {"cpx", "cmpx"},
158 {"cpy", "cmpy"},
159 {0, 0}
162 /* Local functions. */
163 static register_id reg_name_search (char *);
164 static register_id register_name (void);
165 static int cmp_opcode (struct m68hc11_opcode *, struct m68hc11_opcode *);
166 static char *print_opcode_format (struct m68hc11_opcode *, int);
167 static char *skip_whites (char *);
168 static int check_range (long, int);
169 static void print_opcode_list (void);
170 static void get_default_target (void);
171 static void print_insn_format (char *);
172 static int get_operand (operand *, int, long);
173 static void fixup8 (expressionS *, int, int);
174 static void fixup16 (expressionS *, int, int);
175 static void fixup24 (expressionS *, int, int);
176 static unsigned char convert_branch (unsigned char);
177 static char *m68hc11_new_insn (int);
178 static void build_dbranch_insn (struct m68hc11_opcode *,
179 operand *, int, int);
180 static int build_indexed_byte (operand *, int, int);
181 static int build_reg_mode (operand *, int);
183 static struct m68hc11_opcode *find (struct m68hc11_opcode_def *,
184 operand *, int);
185 static struct m68hc11_opcode *find_opcode (struct m68hc11_opcode_def *,
186 operand *, int *);
187 static void build_jump_insn (struct m68hc11_opcode *, operand *, int, int);
188 static void build_insn (struct m68hc11_opcode *, operand *, int);
189 static int relaxable_symbol (symbolS *);
191 /* Pseudo op to indicate a relax group. */
192 static void s_m68hc11_relax (int);
194 /* Pseudo op to control the ELF flags. */
195 static void s_m68hc11_mode (int);
197 /* Mark the symbols with STO_M68HC12_FAR to indicate the functions
198 are using 'rtc' for returning. It is necessary to use 'call'
199 to invoke them. This is also used by the debugger to correctly
200 find the stack frame. */
201 static void s_m68hc11_mark_symbol (int);
203 /* Controls whether relative branches can be turned into long branches.
204 When the relative offset is too large, the insn are changed:
205 bra -> jmp
206 bsr -> jsr
207 bcc -> b!cc +3
208 jmp L
209 dbcc -> db!cc +3
210 jmp L
212 Setting the flag forbidds this. */
213 static short flag_fixed_branches = 0;
215 /* Force to use long jumps (absolute) instead of relative branches. */
216 static short flag_force_long_jumps = 0;
218 /* Change the direct addressing mode into an absolute addressing mode
219 when the insn does not support direct addressing.
220 For example, "clr *ZD0" is normally not possible and is changed
221 into "clr ZDO". */
222 static short flag_strict_direct_addressing = 1;
224 /* When an opcode has invalid operand, print out the syntax of the opcode
225 to stderr. */
226 static short flag_print_insn_syntax = 0;
228 /* Dumps the list of instructions with syntax and then exit:
229 1 -> Only dumps the list (sorted by name)
230 2 -> Generate an example (or test) that can be compiled. */
231 static short flag_print_opcodes = 0;
233 /* Opcode hash table. */
234 static struct hash_control *m68hc11_hash;
236 /* Current cpu (either cpu6811 or cpu6812). This is determined automagically
237 by 'get_default_target' by looking at default BFD vector. This is overridden
238 with the -m<cpu> option. */
239 static int current_architecture = 0;
241 /* Default cpu determined by 'get_default_target'. */
242 static const char *default_cpu;
244 /* Number of opcodes in the sorted table (filtered by current cpu). */
245 static int num_opcodes;
247 /* The opcodes sorted by name and filtered by current cpu. */
248 static struct m68hc11_opcode *m68hc11_sorted_opcodes;
250 /* ELF flags to set in the output file header. */
251 static int elf_flags = E_M68HC11_F64;
253 /* These are the machine dependent pseudo-ops. These are included so
254 the assembler can work on the output from the SUN C compiler, which
255 generates these. */
257 /* This table describes all the machine specific pseudo-ops the assembler
258 has to support. The fields are:
259 pseudo-op name without dot
260 function to call to execute this pseudo-op
261 Integer arg to pass to the function. */
262 const pseudo_typeS md_pseudo_table[] = {
263 /* The following pseudo-ops are supported for MRI compatibility. */
264 {"fcb", cons, 1},
265 {"fdb", cons, 2},
266 {"fcc", stringer, 1},
267 {"rmb", s_space, 0},
269 /* Motorola ALIS. */
270 {"xrefb", s_ignore, 0}, /* Same as xref */
272 /* Gcc driven relaxation. */
273 {"relax", s_m68hc11_relax, 0},
275 /* .mode instruction (ala SH). */
276 {"mode", s_m68hc11_mode, 0},
278 /* .far instruction. */
279 {"far", s_m68hc11_mark_symbol, STO_M68HC12_FAR},
281 /* .interrupt instruction. */
282 {"interrupt", s_m68hc11_mark_symbol, STO_M68HC12_INTERRUPT},
284 {0, 0, 0}
287 /* Options and initialization. */
289 const char *md_shortopts = "Sm:";
291 struct option md_longopts[] = {
292 #define OPTION_FORCE_LONG_BRANCH (OPTION_MD_BASE)
293 {"force-long-branches", no_argument, NULL, OPTION_FORCE_LONG_BRANCH},
294 {"force-long-branchs", no_argument, NULL, OPTION_FORCE_LONG_BRANCH}, /* Misspelt version kept for backwards compatibility. */
296 #define OPTION_SHORT_BRANCHES (OPTION_MD_BASE + 1)
297 {"short-branches", no_argument, NULL, OPTION_SHORT_BRANCHES},
298 {"short-branchs", no_argument, NULL, OPTION_SHORT_BRANCHES}, /* Misspelt version kept for backwards compatibility. */
300 #define OPTION_STRICT_DIRECT_MODE (OPTION_MD_BASE + 2)
301 {"strict-direct-mode", no_argument, NULL, OPTION_STRICT_DIRECT_MODE},
303 #define OPTION_PRINT_INSN_SYNTAX (OPTION_MD_BASE + 3)
304 {"print-insn-syntax", no_argument, NULL, OPTION_PRINT_INSN_SYNTAX},
306 #define OPTION_PRINT_OPCODES (OPTION_MD_BASE + 4)
307 {"print-opcodes", no_argument, NULL, OPTION_PRINT_OPCODES},
309 #define OPTION_GENERATE_EXAMPLE (OPTION_MD_BASE + 5)
310 {"generate-example", no_argument, NULL, OPTION_GENERATE_EXAMPLE},
312 #define OPTION_MSHORT (OPTION_MD_BASE + 6)
313 {"mshort", no_argument, NULL, OPTION_MSHORT},
315 #define OPTION_MLONG (OPTION_MD_BASE + 7)
316 {"mlong", no_argument, NULL, OPTION_MLONG},
318 #define OPTION_MSHORT_DOUBLE (OPTION_MD_BASE + 8)
319 {"mshort-double", no_argument, NULL, OPTION_MSHORT_DOUBLE},
321 #define OPTION_MLONG_DOUBLE (OPTION_MD_BASE + 9)
322 {"mlong-double", no_argument, NULL, OPTION_MLONG_DOUBLE},
324 {NULL, no_argument, NULL, 0}
326 size_t md_longopts_size = sizeof (md_longopts);
328 /* Get the target cpu for the assembler. This is based on the configure
329 options and on the -m68hc11/-m68hc12 option. If no option is specified,
330 we must get the default. */
331 const char *
332 m68hc11_arch_format (void)
334 get_default_target ();
335 if (current_architecture & cpu6811)
336 return "elf32-m68hc11";
337 else
338 return "elf32-m68hc12";
341 enum bfd_architecture
342 m68hc11_arch (void)
344 get_default_target ();
345 if (current_architecture & cpu6811)
346 return bfd_arch_m68hc11;
347 else
348 return bfd_arch_m68hc12;
352 m68hc11_mach (void)
354 return 0;
357 /* Listing header selected according to cpu. */
358 const char *
359 m68hc11_listing_header (void)
361 if (current_architecture & cpu6811)
362 return "M68HC11 GAS ";
363 else
364 return "M68HC12 GAS ";
367 void
368 md_show_usage (FILE *stream)
370 get_default_target ();
371 fprintf (stream, _("\
372 Motorola 68HC11/68HC12/68HCS12 options:\n\
373 -m68hc11 | -m68hc12 |\n\
374 -m68hcs12 specify the processor [default %s]\n\
375 -mshort use 16-bit int ABI (default)\n\
376 -mlong use 32-bit int ABI\n\
377 -mshort-double use 32-bit double ABI\n\
378 -mlong-double use 64-bit double ABI (default)\n\
379 --force-long-branches always turn relative branches into absolute ones\n\
380 -S,--short-branches do not turn relative branches into absolute ones\n\
381 when the offset is out of range\n\
382 --strict-direct-mode do not turn the direct mode into extended mode\n\
383 when the instruction does not support direct mode\n\
384 --print-insn-syntax print the syntax of instruction in case of error\n\
385 --print-opcodes print the list of instructions with syntax\n\
386 --generate-example generate an example of each instruction\n\
387 (used for testing)\n"), default_cpu);
391 /* Try to identify the default target based on the BFD library. */
392 static void
393 get_default_target (void)
395 const bfd_target *target;
396 bfd abfd;
398 if (current_architecture != 0)
399 return;
401 default_cpu = "unknown";
402 target = bfd_find_target (0, &abfd);
403 if (target && target->name)
405 if (strcmp (target->name, "elf32-m68hc12") == 0)
407 current_architecture = cpu6812;
408 default_cpu = "m68hc12";
410 else if (strcmp (target->name, "elf32-m68hc11") == 0)
412 current_architecture = cpu6811;
413 default_cpu = "m68hc11";
415 else
417 as_bad (_("Default target `%s' is not supported."), target->name);
422 void
423 m68hc11_print_statistics (FILE *file)
425 int i;
426 struct m68hc11_opcode_def *opc;
428 hash_print_statistics (file, "opcode table", m68hc11_hash);
430 opc = m68hc11_opcode_defs;
431 if (opc == 0 || m68hc11_nb_opcode_defs == 0)
432 return;
434 /* Dump the opcode statistics table. */
435 fprintf (file, _("Name # Modes Min ops Max ops Modes mask # Used\n"));
436 for (i = 0; i < m68hc11_nb_opcode_defs; i++, opc++)
438 fprintf (file, "%-7.7s %5d %7d %7d 0x%08lx %7d\n",
439 opc->opcode->name,
440 opc->nb_modes,
441 opc->min_operands, opc->max_operands, opc->format, opc->used);
446 md_parse_option (int c, char *arg)
448 get_default_target ();
449 switch (c)
451 /* -S means keep external to 2 bit offset rather than 16 bit one. */
452 case OPTION_SHORT_BRANCHES:
453 case 'S':
454 flag_fixed_branches = 1;
455 break;
457 case OPTION_FORCE_LONG_BRANCH:
458 flag_force_long_jumps = 1;
459 break;
461 case OPTION_PRINT_INSN_SYNTAX:
462 flag_print_insn_syntax = 1;
463 break;
465 case OPTION_PRINT_OPCODES:
466 flag_print_opcodes = 1;
467 break;
469 case OPTION_STRICT_DIRECT_MODE:
470 flag_strict_direct_addressing = 0;
471 break;
473 case OPTION_GENERATE_EXAMPLE:
474 flag_print_opcodes = 2;
475 break;
477 case OPTION_MSHORT:
478 elf_flags &= ~E_M68HC11_I32;
479 break;
481 case OPTION_MLONG:
482 elf_flags |= E_M68HC11_I32;
483 break;
485 case OPTION_MSHORT_DOUBLE:
486 elf_flags &= ~E_M68HC11_F64;
487 break;
489 case OPTION_MLONG_DOUBLE:
490 elf_flags |= E_M68HC11_F64;
491 break;
493 case 'm':
494 if (strcasecmp (arg, "68hc11") == 0)
495 current_architecture = cpu6811;
496 else if (strcasecmp (arg, "68hc12") == 0)
497 current_architecture = cpu6812;
498 else if (strcasecmp (arg, "68hcs12") == 0)
499 current_architecture = cpu6812 | cpu6812s;
500 else
501 as_bad (_("Option `%s' is not recognized."), arg);
502 break;
504 default:
505 return 0;
508 return 1;
511 symbolS *
512 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
514 return 0;
517 /* Equal to MAX_PRECISION in atof-ieee.c. */
518 #define MAX_LITTLENUMS 6
520 /* Turn a string in input_line_pointer into a floating point constant
521 of type TYPE, and store the appropriate bytes in *LITP. The number
522 of LITTLENUMS emitted is stored in *SIZEP. An error message is
523 returned, or NULL on OK. */
524 char *
525 md_atof (int type, char *litP, int *sizeP)
527 int prec;
528 LITTLENUM_TYPE words[MAX_LITTLENUMS];
529 LITTLENUM_TYPE *wordP;
530 char *t;
532 switch (type)
534 case 'f':
535 case 'F':
536 case 's':
537 case 'S':
538 prec = 2;
539 break;
541 case 'd':
542 case 'D':
543 case 'r':
544 case 'R':
545 prec = 4;
546 break;
548 case 'x':
549 case 'X':
550 prec = 6;
551 break;
553 case 'p':
554 case 'P':
555 prec = 6;
556 break;
558 default:
559 *sizeP = 0;
560 return _("Bad call to MD_ATOF()");
562 t = atof_ieee (input_line_pointer, type, words);
563 if (t)
564 input_line_pointer = t;
566 *sizeP = prec * sizeof (LITTLENUM_TYPE);
567 for (wordP = words; prec--;)
569 md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE));
570 litP += sizeof (LITTLENUM_TYPE);
572 return 0;
575 valueT
576 md_section_align (asection *seg, valueT addr)
578 int align = bfd_get_section_alignment (stdoutput, seg);
579 return ((addr + (1 << align) - 1) & (-1 << align));
582 static int
583 cmp_opcode (struct m68hc11_opcode *op1, struct m68hc11_opcode *op2)
585 return strcmp (op1->name, op2->name);
588 #define IS_CALL_SYMBOL(MODE) \
589 (((MODE) & (M6812_OP_PAGE|M6811_OP_IND16)) \
590 == ((M6812_OP_PAGE|M6811_OP_IND16)))
592 /* Initialize the assembler. Create the opcode hash table
593 (sorted on the names) with the M6811 opcode table
594 (from opcode library). */
595 void
596 md_begin (void)
598 char *prev_name = "";
599 struct m68hc11_opcode *opcodes;
600 struct m68hc11_opcode_def *opc = 0;
601 int i, j;
603 get_default_target ();
605 m68hc11_hash = hash_new ();
607 /* Get a writable copy of the opcode table and sort it on the names. */
608 opcodes = (struct m68hc11_opcode *) xmalloc (m68hc11_num_opcodes *
609 sizeof (struct
610 m68hc11_opcode));
611 m68hc11_sorted_opcodes = opcodes;
612 num_opcodes = 0;
613 for (i = 0; i < m68hc11_num_opcodes; i++)
615 if (m68hc11_opcodes[i].arch & current_architecture)
617 opcodes[num_opcodes] = m68hc11_opcodes[i];
618 if (opcodes[num_opcodes].name[0] == 'b'
619 && opcodes[num_opcodes].format & M6811_OP_JUMP_REL
620 && !(opcodes[num_opcodes].format & M6811_OP_BITMASK))
622 num_opcodes++;
623 opcodes[num_opcodes] = m68hc11_opcodes[i];
625 num_opcodes++;
626 for (j = 0; alias_opcodes[j].name != 0; j++)
627 if (strcmp (m68hc11_opcodes[i].name, alias_opcodes[j].name) == 0)
629 opcodes[num_opcodes] = m68hc11_opcodes[i];
630 opcodes[num_opcodes].name = alias_opcodes[j].alias;
631 num_opcodes++;
632 break;
636 qsort (opcodes, num_opcodes, sizeof (struct m68hc11_opcode),
637 (int (*) (const void*, const void*)) cmp_opcode);
639 opc = (struct m68hc11_opcode_def *)
640 xmalloc (num_opcodes * sizeof (struct m68hc11_opcode_def));
641 m68hc11_opcode_defs = opc--;
643 /* Insert unique names into hash table. The M6811 instruction set
644 has several identical opcode names that have different opcodes based
645 on the operands. This hash table then provides a quick index to
646 the first opcode with a particular name in the opcode table. */
647 for (i = 0; i < num_opcodes; i++, opcodes++)
649 int expect;
651 if (strcmp (prev_name, opcodes->name))
653 prev_name = (char *) opcodes->name;
655 opc++;
656 opc->format = 0;
657 opc->min_operands = 100;
658 opc->max_operands = 0;
659 opc->nb_modes = 0;
660 opc->opcode = opcodes;
661 opc->used = 0;
662 hash_insert (m68hc11_hash, opcodes->name, opc);
664 opc->nb_modes++;
665 opc->format |= opcodes->format;
667 /* See how many operands this opcode needs. */
668 expect = 0;
669 if (opcodes->format & M6811_OP_MASK)
670 expect++;
671 if (opcodes->format & M6811_OP_BITMASK)
672 expect++;
673 if (opcodes->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
674 expect++;
675 if (opcodes->format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2))
676 expect++;
677 /* Special case for call instruction. */
678 if ((opcodes->format & M6812_OP_PAGE)
679 && !(opcodes->format & M6811_OP_IND16))
680 expect++;
682 if (expect < opc->min_operands)
683 opc->min_operands = expect;
684 if (IS_CALL_SYMBOL (opcodes->format))
685 expect++;
686 if (expect > opc->max_operands)
687 opc->max_operands = expect;
689 opc++;
690 m68hc11_nb_opcode_defs = opc - m68hc11_opcode_defs;
692 if (flag_print_opcodes)
694 print_opcode_list ();
695 exit (EXIT_SUCCESS);
699 void
700 m68hc11_init_after_args (void)
704 /* Builtin help. */
706 /* Return a string that represents the operand format for the instruction.
707 When example is true, this generates an example of operand. This is used
708 to give an example and also to generate a test. */
709 static char *
710 print_opcode_format (struct m68hc11_opcode *opcode, int example)
712 static char buf[128];
713 int format = opcode->format;
714 char *p;
716 p = buf;
717 buf[0] = 0;
718 if (format & M6811_OP_IMM8)
720 if (example)
721 sprintf (p, "#%d", rand () & 0x0FF);
722 else
723 strcpy (p, _("#<imm8>"));
724 p = &p[strlen (p)];
727 if (format & M6811_OP_IMM16)
729 if (example)
730 sprintf (p, "#%d", rand () & 0x0FFFF);
731 else
732 strcpy (p, _("#<imm16>"));
733 p = &p[strlen (p)];
736 if (format & M6811_OP_IX)
738 if (example)
739 sprintf (p, "%d,X", rand () & 0x0FF);
740 else
741 strcpy (p, _("<imm8>,X"));
742 p = &p[strlen (p)];
745 if (format & M6811_OP_IY)
747 if (example)
748 sprintf (p, "%d,X", rand () & 0x0FF);
749 else
750 strcpy (p, _("<imm8>,X"));
751 p = &p[strlen (p)];
754 if (format & M6812_OP_IDX)
756 if (example)
757 sprintf (p, "%d,X", rand () & 0x0FF);
758 else
759 strcpy (p, "n,r");
760 p = &p[strlen (p)];
763 if (format & M6812_OP_PAGE)
765 if (example)
766 sprintf (p, ", %d", rand () & 0x0FF);
767 else
768 strcpy (p, ", <page>");
769 p = &p[strlen (p)];
772 if (format & M6811_OP_DIRECT)
774 if (example)
775 sprintf (p, "*Z%d", rand () & 0x0FF);
776 else
777 strcpy (p, _("*<abs8>"));
778 p = &p[strlen (p)];
781 if (format & M6811_OP_BITMASK)
783 if (buf[0])
784 *p++ = ' ';
786 if (example)
787 sprintf (p, "#$%02x", rand () & 0x0FF);
788 else
789 strcpy (p, _("#<mask>"));
791 p = &p[strlen (p)];
792 if (format & M6811_OP_JUMP_REL)
793 *p++ = ' ';
796 if (format & M6811_OP_IND16)
798 if (example)
799 sprintf (p, _("symbol%d"), rand () & 0x0FF);
800 else
801 strcpy (p, _("<abs>"));
803 p = &p[strlen (p)];
806 if (format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
808 if (example)
810 if (format & M6811_OP_BITMASK)
812 sprintf (p, ".+%d", rand () & 0x7F);
814 else
816 sprintf (p, "L%d", rand () & 0x0FF);
819 else
820 strcpy (p, _("<label>"));
823 return buf;
826 /* Prints the list of instructions with the possible operands. */
827 static void
828 print_opcode_list (void)
830 int i;
831 char *prev_name = "";
832 struct m68hc11_opcode *opcodes;
833 int example = flag_print_opcodes == 2;
835 if (example)
836 printf (_("# Example of `%s' instructions\n\t.sect .text\n_start:\n"),
837 default_cpu);
839 opcodes = m68hc11_sorted_opcodes;
841 /* Walk the list sorted on names (by md_begin). We only report
842 one instruction per line, and we collect the different operand
843 formats. */
844 for (i = 0; i < num_opcodes; i++, opcodes++)
846 char *fmt = print_opcode_format (opcodes, example);
848 if (example)
850 printf ("L%d:\t", i);
851 printf ("%s %s\n", opcodes->name, fmt);
853 else
855 if (strcmp (prev_name, opcodes->name))
857 if (i > 0)
858 printf ("\n");
860 printf ("%-5.5s ", opcodes->name);
861 prev_name = (char *) opcodes->name;
863 if (fmt[0])
864 printf (" [%s]", fmt);
867 printf ("\n");
870 /* Print the instruction format. This operation is called when some
871 instruction is not correct. Instruction format is printed as an
872 error message. */
873 static void
874 print_insn_format (char *name)
876 struct m68hc11_opcode_def *opc;
877 struct m68hc11_opcode *opcode;
878 char buf[128];
880 opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash, name);
881 if (opc == NULL)
883 as_bad (_("Instruction `%s' is not recognized."), name);
884 return;
886 opcode = opc->opcode;
888 as_bad (_("Instruction formats for `%s':"), name);
891 char *fmt;
893 fmt = print_opcode_format (opcode, 0);
894 sprintf (buf, "\t%-5.5s %s", opcode->name, fmt);
896 as_bad ("%s", buf);
897 opcode++;
899 while (strcmp (opcode->name, name) == 0);
902 /* Analysis of 68HC11 and 68HC12 operands. */
904 /* reg_name_search() finds the register number given its name.
905 Returns the register number or REG_NONE on failure. */
906 static register_id
907 reg_name_search (char *name)
909 if (strcasecmp (name, "x") == 0 || strcasecmp (name, "ix") == 0)
910 return REG_X;
911 if (strcasecmp (name, "y") == 0 || strcasecmp (name, "iy") == 0)
912 return REG_Y;
913 if (strcasecmp (name, "a") == 0)
914 return REG_A;
915 if (strcasecmp (name, "b") == 0)
916 return REG_B;
917 if (strcasecmp (name, "d") == 0)
918 return REG_D;
919 if (strcasecmp (name, "sp") == 0)
920 return REG_SP;
921 if (strcasecmp (name, "pc") == 0)
922 return REG_PC;
923 if (strcasecmp (name, "ccr") == 0)
924 return REG_CCR;
926 return REG_NONE;
929 static char *
930 skip_whites (char *p)
932 while (*p == ' ' || *p == '\t')
933 p++;
935 return p;
938 /* Check the string at input_line_pointer
939 to see if it is a valid register name. */
940 static register_id
941 register_name (void)
943 register_id reg_number;
944 char c, *p = input_line_pointer;
946 if (!is_name_beginner (*p++))
947 return REG_NONE;
949 while (is_part_of_name (*p++))
950 continue;
952 c = *--p;
953 if (c)
954 *p++ = 0;
956 /* Look to see if it's in the register table. */
957 reg_number = reg_name_search (input_line_pointer);
958 if (reg_number != REG_NONE)
960 if (c)
961 *--p = c;
963 input_line_pointer = p;
964 return reg_number;
966 if (c)
967 *--p = c;
969 return reg_number;
971 #define M6811_OP_CALL_ADDR 0x00800000
972 #define M6811_OP_PAGE_ADDR 0x04000000
974 /* Parse a string of operands and return an array of expressions.
976 Operand mode[0] mode[1] exp[0] exp[1]
977 #n M6811_OP_IMM16 - O_*
978 *<exp> M6811_OP_DIRECT - O_*
979 .{+-}<exp> M6811_OP_JUMP_REL - O_*
980 <exp> M6811_OP_IND16 - O_*
981 ,r N,r M6812_OP_IDX M6812_OP_REG O_constant O_register
982 n,-r M6812_PRE_DEC M6812_OP_REG O_constant O_register
983 n,+r M6812_PRE_INC " "
984 n,r- M6812_POST_DEC " "
985 n,r+ M6812_POST_INC " "
986 A,r B,r D,r M6811_OP_REG M6812_OP_REG O_register O_register
987 [D,r] M6811_OP_D_IDX M6812_OP_REG O_register O_register
988 [n,r] M6811_OP_D_IDX_2 M6812_OP_REG O_constant O_register */
989 static int
990 get_operand (operand *oper, int which, long opmode)
992 char *p = input_line_pointer;
993 int mode;
994 register_id reg;
996 oper->exp.X_op = O_absent;
997 oper->reg1 = REG_NONE;
998 oper->reg2 = REG_NONE;
999 mode = M6811_OP_NONE;
1001 p = skip_whites (p);
1003 if (*p == 0 || *p == '\n' || *p == '\r')
1005 input_line_pointer = p;
1006 return 0;
1009 if (*p == '*' && (opmode & (M6811_OP_DIRECT | M6811_OP_IND16)))
1011 mode = M6811_OP_DIRECT;
1012 p++;
1014 else if (*p == '#')
1016 if (!(opmode & (M6811_OP_IMM8 | M6811_OP_IMM16 | M6811_OP_BITMASK)))
1018 as_bad (_("Immediate operand is not allowed for operand %d."),
1019 which);
1020 return -1;
1023 mode = M6811_OP_IMM16;
1024 p++;
1025 if (strncmp (p, "%hi", 3) == 0)
1027 p += 3;
1028 mode |= M6811_OP_HIGH_ADDR;
1030 else if (strncmp (p, "%lo", 3) == 0)
1032 p += 3;
1033 mode |= M6811_OP_LOW_ADDR;
1035 /* %page modifier is used to obtain only the page number
1036 of the address of a function. */
1037 else if (strncmp (p, "%page", 5) == 0)
1039 p += 5;
1040 mode |= M6811_OP_PAGE_ADDR;
1043 /* %addr modifier is used to obtain the physical address part
1044 of the function (16-bit). For 68HC12 the function will be
1045 mapped in the 16K window at 0x8000 and the value will be
1046 within that window (although the function address may not fit
1047 in 16-bit). See bfd/elf32-m68hc12.c for the translation. */
1048 else if (strncmp (p, "%addr", 5) == 0)
1050 p += 5;
1051 mode |= M6811_OP_CALL_ADDR;
1054 else if (*p == '.' && (p[1] == '+' || p[1] == '-'))
1056 p++;
1057 mode = M6811_OP_JUMP_REL;
1059 else if (*p == '[')
1061 if (current_architecture & cpu6811)
1062 as_bad (_("Indirect indexed addressing is not valid for 68HC11."));
1064 p++;
1065 mode = M6812_OP_D_IDX;
1066 p = skip_whites (p);
1068 else if (*p == ',') /* Special handling of ,x and ,y. */
1070 p++;
1071 input_line_pointer = p;
1073 reg = register_name ();
1074 if (reg != REG_NONE)
1076 oper->reg1 = reg;
1077 oper->exp.X_op = O_constant;
1078 oper->exp.X_add_number = 0;
1079 oper->mode = M6812_OP_IDX;
1080 return 1;
1082 as_bad (_("Spurious `,' or bad indirect register addressing mode."));
1083 return -1;
1085 /* Handle 68HC12 page specification in 'call foo,%page(bar)'. */
1086 else if ((opmode & M6812_OP_PAGE) && strncmp (p, "%page", 5) == 0)
1088 p += 5;
1089 mode = M6811_OP_PAGE_ADDR | M6812_OP_PAGE | M6811_OP_IND16;
1091 input_line_pointer = p;
1093 if (mode == M6811_OP_NONE || mode == M6812_OP_D_IDX)
1094 reg = register_name ();
1095 else
1096 reg = REG_NONE;
1098 if (reg != REG_NONE)
1100 p = skip_whites (input_line_pointer);
1101 if (*p == ']' && mode == M6812_OP_D_IDX)
1103 as_bad
1104 (_("Missing second register or offset for indexed-indirect mode."));
1105 return -1;
1108 oper->reg1 = reg;
1109 oper->mode = mode | M6812_OP_REG;
1110 if (*p != ',')
1112 if (mode == M6812_OP_D_IDX)
1114 as_bad (_("Missing second register for indexed-indirect mode."));
1115 return -1;
1117 return 1;
1120 p++;
1121 input_line_pointer = p;
1122 reg = register_name ();
1123 if (reg != REG_NONE)
1125 p = skip_whites (input_line_pointer);
1126 if (mode == M6812_OP_D_IDX)
1128 if (*p != ']')
1130 as_bad (_("Missing `]' to close indexed-indirect mode."));
1131 return -1;
1133 p++;
1134 oper->mode = M6812_OP_D_IDX;
1136 input_line_pointer = p;
1138 oper->reg2 = reg;
1139 return 1;
1141 return 1;
1144 /* In MRI mode, isolate the operand because we can't distinguish
1145 operands from comments. */
1146 if (flag_mri)
1148 char c = 0;
1150 p = skip_whites (p);
1151 while (*p && *p != ' ' && *p != '\t')
1152 p++;
1154 if (*p)
1156 c = *p;
1157 *p = 0;
1160 /* Parse as an expression. */
1161 expression (&oper->exp);
1163 if (c)
1165 *p = c;
1168 else
1170 expression (&oper->exp);
1173 if (oper->exp.X_op == O_illegal)
1175 as_bad (_("Illegal operand."));
1176 return -1;
1178 else if (oper->exp.X_op == O_absent)
1180 as_bad (_("Missing operand."));
1181 return -1;
1184 p = input_line_pointer;
1186 if (mode == M6811_OP_NONE || mode == M6811_OP_DIRECT
1187 || mode == M6812_OP_D_IDX)
1189 p = skip_whites (input_line_pointer);
1191 if (*p == ',')
1193 int possible_mode = M6811_OP_NONE;
1194 char *old_input_line;
1196 old_input_line = p;
1197 p++;
1199 /* 68HC12 pre increment or decrement. */
1200 if (mode == M6811_OP_NONE)
1202 if (*p == '-')
1204 possible_mode = M6812_PRE_DEC;
1205 p++;
1207 else if (*p == '+')
1209 possible_mode = M6812_PRE_INC;
1210 p++;
1212 p = skip_whites (p);
1214 input_line_pointer = p;
1215 reg = register_name ();
1217 /* Backtrack if we have a valid constant expression and
1218 it does not correspond to the offset of the 68HC12 indexed
1219 addressing mode (as in N,x). */
1220 if (reg == REG_NONE && mode == M6811_OP_NONE
1221 && possible_mode != M6811_OP_NONE)
1223 oper->mode = M6811_OP_IND16 | M6811_OP_JUMP_REL;
1224 input_line_pointer = skip_whites (old_input_line);
1225 return 1;
1228 if (possible_mode != M6811_OP_NONE)
1229 mode = possible_mode;
1231 if ((current_architecture & cpu6811)
1232 && possible_mode != M6811_OP_NONE)
1233 as_bad (_("Pre-increment mode is not valid for 68HC11"));
1234 /* Backtrack. */
1235 if (which == 0 && opmode & M6812_OP_IDX_P2
1236 && reg != REG_X && reg != REG_Y
1237 && reg != REG_PC && reg != REG_SP)
1239 reg = REG_NONE;
1240 input_line_pointer = p;
1243 if (reg == REG_NONE && mode != M6811_OP_DIRECT
1244 && !(mode == M6811_OP_NONE && opmode & M6811_OP_IND16))
1246 as_bad (_("Wrong register in register indirect mode."));
1247 return -1;
1249 if (mode == M6812_OP_D_IDX)
1251 p = skip_whites (input_line_pointer);
1252 if (*p++ != ']')
1254 as_bad (_("Missing `]' to close register indirect operand."));
1255 return -1;
1257 input_line_pointer = p;
1258 oper->reg1 = reg;
1259 oper->mode = M6812_OP_D_IDX_2;
1260 return 1;
1262 if (reg != REG_NONE)
1264 oper->reg1 = reg;
1265 if (mode == M6811_OP_NONE)
1267 p = input_line_pointer;
1268 if (*p == '-')
1270 mode = M6812_POST_DEC;
1271 p++;
1272 if (current_architecture & cpu6811)
1273 as_bad
1274 (_("Post-decrement mode is not valid for 68HC11."));
1276 else if (*p == '+')
1278 mode = M6812_POST_INC;
1279 p++;
1280 if (current_architecture & cpu6811)
1281 as_bad
1282 (_("Post-increment mode is not valid for 68HC11."));
1284 else
1285 mode = M6812_OP_IDX;
1287 input_line_pointer = p;
1289 else
1290 mode |= M6812_OP_IDX;
1292 oper->mode = mode;
1293 return 1;
1295 input_line_pointer = old_input_line;
1298 if (mode == M6812_OP_D_IDX_2)
1300 as_bad (_("Invalid indexed indirect mode."));
1301 return -1;
1305 /* If the mode is not known until now, this is either a label
1306 or an indirect address. */
1307 if (mode == M6811_OP_NONE)
1308 mode = M6811_OP_IND16 | M6811_OP_JUMP_REL;
1310 p = input_line_pointer;
1311 while (*p == ' ' || *p == '\t')
1312 p++;
1313 input_line_pointer = p;
1314 oper->mode = mode;
1316 return 1;
1319 #define M6812_AUTO_INC_DEC (M6812_PRE_INC | M6812_PRE_DEC \
1320 | M6812_POST_INC | M6812_POST_DEC)
1322 /* Checks that the number 'num' fits for a given mode. */
1323 static int
1324 check_range (long num, int mode)
1326 /* Auto increment and decrement are ok for [-8..8] without 0. */
1327 if (mode & M6812_AUTO_INC_DEC)
1328 return (num != 0 && num <= 8 && num >= -8);
1330 /* The 68HC12 supports 5, 9 and 16-bit offsets. */
1331 if (mode & (M6812_INDEXED_IND | M6812_INDEXED | M6812_OP_IDX))
1332 mode = M6811_OP_IND16;
1334 if (mode & M6812_OP_JUMP_REL16)
1335 mode = M6811_OP_IND16;
1337 mode &= ~M6811_OP_BRANCH;
1338 switch (mode)
1340 case M6811_OP_IX:
1341 case M6811_OP_IY:
1342 case M6811_OP_DIRECT:
1343 return (num >= 0 && num <= 255) ? 1 : 0;
1345 case M6811_OP_BITMASK:
1346 case M6811_OP_IMM8:
1347 case M6812_OP_PAGE:
1348 return (((num & 0xFFFFFF00) == 0) || ((num & 0xFFFFFF00) == 0xFFFFFF00))
1349 ? 1 : 0;
1351 case M6811_OP_JUMP_REL:
1352 return (num >= -128 && num <= 127) ? 1 : 0;
1354 case M6811_OP_IND16:
1355 case M6811_OP_IND16 | M6812_OP_PAGE:
1356 case M6811_OP_IMM16:
1357 return (((num & 0xFFFF0000) == 0) || ((num & 0xFFFF0000) == 0xFFFF0000))
1358 ? 1 : 0;
1360 case M6812_OP_IBCC_MARKER:
1361 case M6812_OP_TBCC_MARKER:
1362 case M6812_OP_DBCC_MARKER:
1363 return (num >= -256 && num <= 255) ? 1 : 0;
1365 case M6812_OP_TRAP_ID:
1366 return ((num >= 0x30 && num <= 0x39)
1367 || (num >= 0x40 && num <= 0x0ff)) ? 1 : 0;
1369 default:
1370 return 0;
1374 /* Gas fixup generation. */
1376 /* Put a 1 byte expression described by 'oper'. If this expression contains
1377 unresolved symbols, generate an 8-bit fixup. */
1378 static void
1379 fixup8 (expressionS *oper, int mode, int opmode)
1381 char *f;
1383 f = frag_more (1);
1385 if (oper->X_op == O_constant)
1387 if (mode & M6812_OP_TRAP_ID
1388 && !check_range (oper->X_add_number, M6812_OP_TRAP_ID))
1390 static char trap_id_warn_once = 0;
1392 as_bad (_("Trap id `%ld' is out of range."), oper->X_add_number);
1393 if (trap_id_warn_once == 0)
1395 trap_id_warn_once = 1;
1396 as_bad (_("Trap id must be within [0x30..0x39] or [0x40..0xff]."));
1400 if (!(mode & M6812_OP_TRAP_ID)
1401 && !check_range (oper->X_add_number, mode))
1403 as_bad (_("Operand out of 8-bit range: `%ld'."), oper->X_add_number);
1405 number_to_chars_bigendian (f, oper->X_add_number & 0x0FF, 1);
1407 else if (oper->X_op != O_register)
1409 if (mode & M6812_OP_TRAP_ID)
1410 as_bad (_("The trap id must be a constant."));
1412 if (mode == M6811_OP_JUMP_REL)
1414 fixS *fixp;
1416 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
1417 oper, TRUE, BFD_RELOC_8_PCREL);
1418 fixp->fx_pcrel_adjust = 1;
1420 else
1422 fixS *fixp;
1423 int reloc;
1425 /* Now create an 8-bit fixup. If there was some %hi, %lo
1426 or %page modifier, generate the reloc accordingly. */
1427 if (opmode & M6811_OP_HIGH_ADDR)
1428 reloc = BFD_RELOC_M68HC11_HI8;
1429 else if (opmode & M6811_OP_LOW_ADDR)
1430 reloc = BFD_RELOC_M68HC11_LO8;
1431 else if (opmode & M6811_OP_PAGE_ADDR)
1432 reloc = BFD_RELOC_M68HC11_PAGE;
1433 else
1434 reloc = BFD_RELOC_8;
1436 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
1437 oper, FALSE, reloc);
1438 if (reloc != BFD_RELOC_8)
1439 fixp->fx_no_overflow = 1;
1441 number_to_chars_bigendian (f, 0, 1);
1443 else
1445 as_fatal (_("Operand `%x' not recognized in fixup8."), oper->X_op);
1449 /* Put a 2 byte expression described by 'oper'. If this expression contains
1450 unresolved symbols, generate a 16-bit fixup. */
1451 static void
1452 fixup16 (expressionS *oper, int mode, int opmode ATTRIBUTE_UNUSED)
1454 char *f;
1456 f = frag_more (2);
1458 if (oper->X_op == O_constant)
1460 if (!check_range (oper->X_add_number, mode))
1462 as_bad (_("Operand out of 16-bit range: `%ld'."),
1463 oper->X_add_number);
1465 number_to_chars_bigendian (f, oper->X_add_number & 0x0FFFF, 2);
1467 else if (oper->X_op != O_register)
1469 fixS *fixp;
1470 int reloc;
1472 if ((opmode & M6811_OP_CALL_ADDR) && (mode & M6811_OP_IMM16))
1473 reloc = BFD_RELOC_M68HC11_LO16;
1474 else if (mode & M6812_OP_JUMP_REL16)
1475 reloc = BFD_RELOC_16_PCREL;
1476 else if (mode & M6812_OP_PAGE)
1477 reloc = BFD_RELOC_M68HC11_LO16;
1478 else
1479 reloc = BFD_RELOC_16;
1481 /* Now create a 16-bit fixup. */
1482 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 2,
1483 oper,
1484 reloc == BFD_RELOC_16_PCREL,
1485 reloc);
1486 number_to_chars_bigendian (f, 0, 2);
1487 if (reloc == BFD_RELOC_16_PCREL)
1488 fixp->fx_pcrel_adjust = 2;
1489 if (reloc == BFD_RELOC_M68HC11_LO16)
1490 fixp->fx_no_overflow = 1;
1492 else
1494 as_fatal (_("Operand `%x' not recognized in fixup16."), oper->X_op);
1498 /* Put a 3 byte expression described by 'oper'. If this expression contains
1499 unresolved symbols, generate a 24-bit fixup. */
1500 static void
1501 fixup24 (expressionS *oper, int mode, int opmode ATTRIBUTE_UNUSED)
1503 char *f;
1505 f = frag_more (3);
1507 if (oper->X_op == O_constant)
1509 if (!check_range (oper->X_add_number, mode))
1511 as_bad (_("Operand out of 16-bit range: `%ld'."),
1512 oper->X_add_number);
1514 number_to_chars_bigendian (f, oper->X_add_number & 0x0FFFFFF, 3);
1516 else if (oper->X_op != O_register)
1518 fixS *fixp;
1520 /* Now create a 24-bit fixup. */
1521 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 3,
1522 oper, FALSE, BFD_RELOC_M68HC11_24);
1523 number_to_chars_bigendian (f, 0, 3);
1525 else
1527 as_fatal (_("Operand `%x' not recognized in fixup16."), oper->X_op);
1531 /* 68HC11 and 68HC12 code generation. */
1533 /* Translate the short branch/bsr instruction into a long branch. */
1534 static unsigned char
1535 convert_branch (unsigned char code)
1537 if (IS_OPCODE (code, M6812_BSR))
1538 return M6812_JSR;
1539 else if (IS_OPCODE (code, M6811_BSR))
1540 return M6811_JSR;
1541 else if (IS_OPCODE (code, M6811_BRA))
1542 return (current_architecture & cpu6812) ? M6812_JMP : M6811_JMP;
1543 else
1544 as_fatal (_("Unexpected branch conversion with `%x'"), code);
1546 /* Keep gcc happy. */
1547 return M6811_JSR;
1550 /* Start a new insn that contains at least 'size' bytes. Record the
1551 line information of that insn in the dwarf2 debug sections. */
1552 static char *
1553 m68hc11_new_insn (int size)
1555 char *f;
1557 f = frag_more (size);
1559 dwarf2_emit_insn (size);
1561 return f;
1564 /* Builds a jump instruction (bra, bcc, bsr). */
1565 static void
1566 build_jump_insn (struct m68hc11_opcode *opcode, operand operands[],
1567 int nb_operands, int jmp_mode)
1569 unsigned char code;
1570 char *f;
1571 unsigned long n;
1572 fragS *frag;
1573 int where;
1575 /* The relative branch conversion is not supported for
1576 brclr and brset. */
1577 assert ((opcode->format & M6811_OP_BITMASK) == 0);
1578 assert (nb_operands == 1);
1579 assert (operands[0].reg1 == REG_NONE && operands[0].reg2 == REG_NONE);
1581 code = opcode->opcode;
1583 n = operands[0].exp.X_add_number;
1585 /* Turn into a long branch:
1586 - when force long branch option (and not for jbcc pseudos),
1587 - when jbcc and the constant is out of -128..127 range,
1588 - when branch optimization is allowed and branch out of range. */
1589 if ((jmp_mode == 0 && flag_force_long_jumps)
1590 || (operands[0].exp.X_op == O_constant
1591 && (!check_range (n, opcode->format) &&
1592 (jmp_mode == 1 || flag_fixed_branches == 0))))
1594 frag = frag_now;
1595 where = frag_now_fix ();
1597 fix_new (frag_now, frag_now_fix (), 0,
1598 &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
1600 if (code == M6811_BSR || code == M6811_BRA || code == M6812_BSR)
1602 code = convert_branch (code);
1604 f = m68hc11_new_insn (1);
1605 number_to_chars_bigendian (f, code, 1);
1607 else if (current_architecture & cpu6812)
1609 /* 68HC12: translate the bcc into a lbcc. */
1610 f = m68hc11_new_insn (2);
1611 number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1);
1612 number_to_chars_bigendian (f + 1, code, 1);
1613 fixup16 (&operands[0].exp, M6812_OP_JUMP_REL16,
1614 M6812_OP_JUMP_REL16);
1615 return;
1617 else
1619 /* 68HC11: translate the bcc into b!cc +3; jmp <L>. */
1620 f = m68hc11_new_insn (3);
1621 code ^= 1;
1622 number_to_chars_bigendian (f, code, 1);
1623 number_to_chars_bigendian (f + 1, 3, 1);
1624 number_to_chars_bigendian (f + 2, M6811_JMP, 1);
1626 fixup16 (&operands[0].exp, M6811_OP_IND16, M6811_OP_IND16);
1627 return;
1630 /* Branch with a constant that must fit in 8-bits. */
1631 if (operands[0].exp.X_op == O_constant)
1633 if (!check_range (n, opcode->format))
1635 as_bad (_("Operand out of range for a relative branch: `%ld'"),
1638 else if (opcode->format & M6812_OP_JUMP_REL16)
1640 f = m68hc11_new_insn (4);
1641 number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1);
1642 number_to_chars_bigendian (f + 1, code, 1);
1643 number_to_chars_bigendian (f + 2, n & 0x0ffff, 2);
1645 else
1647 f = m68hc11_new_insn (2);
1648 number_to_chars_bigendian (f, code, 1);
1649 number_to_chars_bigendian (f + 1, n & 0x0FF, 1);
1652 else if (opcode->format & M6812_OP_JUMP_REL16)
1654 frag = frag_now;
1655 where = frag_now_fix ();
1657 fix_new (frag_now, frag_now_fix (), 0,
1658 &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
1660 f = m68hc11_new_insn (2);
1661 number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1);
1662 number_to_chars_bigendian (f + 1, code, 1);
1663 fixup16 (&operands[0].exp, M6812_OP_JUMP_REL16, M6812_OP_JUMP_REL16);
1665 else
1667 char *opcode;
1669 frag = frag_now;
1670 where = frag_now_fix ();
1672 fix_new (frag_now, frag_now_fix (), 0,
1673 &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
1675 /* Branch offset must fit in 8-bits, don't do some relax. */
1676 if (jmp_mode == 0 && flag_fixed_branches)
1678 opcode = m68hc11_new_insn (1);
1679 number_to_chars_bigendian (opcode, code, 1);
1680 fixup8 (&operands[0].exp, M6811_OP_JUMP_REL, M6811_OP_JUMP_REL);
1683 /* bra/bsr made be changed into jmp/jsr. */
1684 else if (code == M6811_BSR || code == M6811_BRA || code == M6812_BSR)
1686 /* Allocate worst case storage. */
1687 opcode = m68hc11_new_insn (3);
1688 number_to_chars_bigendian (opcode, code, 1);
1689 number_to_chars_bigendian (opcode + 1, 0, 1);
1690 frag_variant (rs_machine_dependent, 1, 1,
1691 ENCODE_RELAX (STATE_PC_RELATIVE, STATE_UNDF),
1692 operands[0].exp.X_add_symbol, (offsetT) n,
1693 opcode);
1695 else if (current_architecture & cpu6812)
1697 opcode = m68hc11_new_insn (2);
1698 number_to_chars_bigendian (opcode, code, 1);
1699 number_to_chars_bigendian (opcode + 1, 0, 1);
1700 frag_var (rs_machine_dependent, 2, 2,
1701 ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_UNDF),
1702 operands[0].exp.X_add_symbol, (offsetT) n, opcode);
1704 else
1706 opcode = m68hc11_new_insn (2);
1707 number_to_chars_bigendian (opcode, code, 1);
1708 number_to_chars_bigendian (opcode + 1, 0, 1);
1709 frag_var (rs_machine_dependent, 3, 3,
1710 ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_UNDF),
1711 operands[0].exp.X_add_symbol, (offsetT) n, opcode);
1716 /* Builds a dbne/dbeq/tbne/tbeq instruction. */
1717 static void
1718 build_dbranch_insn (struct m68hc11_opcode *opcode, operand operands[],
1719 int nb_operands, int jmp_mode)
1721 unsigned char code;
1722 char *f;
1723 unsigned long n;
1725 /* The relative branch conversion is not supported for
1726 brclr and brset. */
1727 assert ((opcode->format & M6811_OP_BITMASK) == 0);
1728 assert (nb_operands == 2);
1729 assert (operands[0].reg1 != REG_NONE);
1731 code = opcode->opcode & 0x0FF;
1733 f = m68hc11_new_insn (1);
1734 number_to_chars_bigendian (f, code, 1);
1736 n = operands[1].exp.X_add_number;
1737 code = operands[0].reg1;
1739 if (operands[0].reg1 == REG_NONE || operands[0].reg1 == REG_CCR
1740 || operands[0].reg1 == REG_PC)
1741 as_bad (_("Invalid register for dbcc/tbcc instruction."));
1743 if (opcode->format & M6812_OP_IBCC_MARKER)
1744 code |= 0x80;
1745 else if (opcode->format & M6812_OP_TBCC_MARKER)
1746 code |= 0x40;
1748 if (!(opcode->format & M6812_OP_EQ_MARKER))
1749 code |= 0x20;
1751 /* Turn into a long branch:
1752 - when force long branch option (and not for jbcc pseudos),
1753 - when jdbcc and the constant is out of -256..255 range,
1754 - when branch optimization is allowed and branch out of range. */
1755 if ((jmp_mode == 0 && flag_force_long_jumps)
1756 || (operands[1].exp.X_op == O_constant
1757 && (!check_range (n, M6812_OP_IBCC_MARKER) &&
1758 (jmp_mode == 1 || flag_fixed_branches == 0))))
1760 f = frag_more (2);
1761 code ^= 0x20;
1762 number_to_chars_bigendian (f, code, 1);
1763 number_to_chars_bigendian (f + 1, M6812_JMP, 1);
1764 fixup16 (&operands[0].exp, M6811_OP_IND16, M6811_OP_IND16);
1765 return;
1768 /* Branch with a constant that must fit in 9-bits. */
1769 if (operands[1].exp.X_op == O_constant)
1771 if (!check_range (n, M6812_OP_IBCC_MARKER))
1773 as_bad (_("Operand out of range for a relative branch: `%ld'"),
1776 else
1778 if ((long) n < 0)
1779 code |= 0x10;
1781 f = frag_more (2);
1782 number_to_chars_bigendian (f, code, 1);
1783 number_to_chars_bigendian (f + 1, n & 0x0FF, 1);
1786 else
1788 /* Branch offset must fit in 8-bits, don't do some relax. */
1789 if (jmp_mode == 0 && flag_fixed_branches)
1791 fixup8 (&operands[0].exp, M6811_OP_JUMP_REL, M6811_OP_JUMP_REL);
1794 else
1796 f = frag_more (2);
1797 number_to_chars_bigendian (f, code, 1);
1798 number_to_chars_bigendian (f + 1, 0, 1);
1799 frag_var (rs_machine_dependent, 3, 3,
1800 ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_UNDF),
1801 operands[1].exp.X_add_symbol, (offsetT) n, f);
1806 #define OP_EXTENDED (M6811_OP_PAGE2 | M6811_OP_PAGE3 | M6811_OP_PAGE4)
1808 /* Assemble the post index byte for 68HC12 extended addressing modes. */
1809 static int
1810 build_indexed_byte (operand *op, int format ATTRIBUTE_UNUSED, int move_insn)
1812 unsigned char byte = 0;
1813 char *f;
1814 int mode;
1815 long val;
1817 val = op->exp.X_add_number;
1818 mode = op->mode;
1819 if (mode & M6812_AUTO_INC_DEC)
1821 byte = 0x20;
1822 if (mode & (M6812_POST_INC | M6812_POST_DEC))
1823 byte |= 0x10;
1825 if (op->exp.X_op == O_constant)
1827 if (!check_range (val, mode))
1829 as_bad (_("Increment/decrement value is out of range: `%ld'."),
1830 val);
1832 if (mode & (M6812_POST_INC | M6812_PRE_INC))
1833 byte |= (val - 1) & 0x07;
1834 else
1835 byte |= (8 - ((val) & 7)) | 0x8;
1837 switch (op->reg1)
1839 case REG_NONE:
1840 as_fatal (_("Expecting a register."));
1842 case REG_X:
1843 byte |= 0;
1844 break;
1846 case REG_Y:
1847 byte |= 0x40;
1848 break;
1850 case REG_SP:
1851 byte |= 0x80;
1852 break;
1854 default:
1855 as_bad (_("Invalid register for post/pre increment."));
1856 break;
1859 f = frag_more (1);
1860 number_to_chars_bigendian (f, byte, 1);
1861 return 1;
1864 if (mode & (M6812_OP_IDX | M6812_OP_D_IDX_2))
1866 switch (op->reg1)
1868 case REG_X:
1869 byte = 0;
1870 break;
1872 case REG_Y:
1873 byte = 1;
1874 break;
1876 case REG_SP:
1877 byte = 2;
1878 break;
1880 case REG_PC:
1881 byte = 3;
1882 break;
1884 default:
1885 as_bad (_("Invalid register."));
1886 break;
1888 if (op->exp.X_op == O_constant)
1890 if (!check_range (val, M6812_OP_IDX))
1892 as_bad (_("Offset out of 16-bit range: %ld."), val);
1895 if (move_insn && !(val >= -16 && val <= 15))
1897 as_bad (_("Offset out of 5-bit range for movw/movb insn: %ld."),
1898 val);
1899 return -1;
1902 if (val >= -16 && val <= 15 && !(mode & M6812_OP_D_IDX_2))
1904 byte = byte << 6;
1905 byte |= val & 0x1f;
1906 f = frag_more (1);
1907 number_to_chars_bigendian (f, byte, 1);
1908 return 1;
1910 else if (val >= -256 && val <= 255 && !(mode & M6812_OP_D_IDX_2))
1912 byte = byte << 3;
1913 byte |= 0xe0;
1914 if (val < 0)
1915 byte |= 0x1;
1916 f = frag_more (2);
1917 number_to_chars_bigendian (f, byte, 1);
1918 number_to_chars_bigendian (f + 1, val & 0x0FF, 1);
1919 return 2;
1921 else
1923 byte = byte << 3;
1924 if (mode & M6812_OP_D_IDX_2)
1925 byte |= 0xe3;
1926 else
1927 byte |= 0xe2;
1929 f = frag_more (3);
1930 number_to_chars_bigendian (f, byte, 1);
1931 number_to_chars_bigendian (f + 1, val & 0x0FFFF, 2);
1932 return 3;
1935 if (mode & M6812_OP_D_IDX_2)
1937 byte = (byte << 3) | 0xe3;
1938 f = frag_more (1);
1939 number_to_chars_bigendian (f, byte, 1);
1941 fixup16 (&op->exp, 0, 0);
1943 else if (op->reg1 != REG_PC)
1945 symbolS *sym;
1946 offsetT off;
1948 f = frag_more (1);
1949 number_to_chars_bigendian (f, byte, 1);
1950 sym = op->exp.X_add_symbol;
1951 off = op->exp.X_add_number;
1952 if (op->exp.X_op != O_symbol)
1954 sym = make_expr_symbol (&op->exp);
1955 off = 0;
1957 /* movb/movw cannot be relaxed. */
1958 if (move_insn)
1960 byte <<= 6;
1961 number_to_chars_bigendian (f, byte, 1);
1962 fix_new (frag_now, f - frag_now->fr_literal, 1,
1963 sym, off, 0, BFD_RELOC_M68HC12_5B);
1964 return 1;
1966 else
1968 number_to_chars_bigendian (f, byte, 1);
1969 frag_var (rs_machine_dependent, 2, 2,
1970 ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_UNDF),
1971 sym, off, f);
1974 else
1976 f = frag_more (1);
1977 /* movb/movw cannot be relaxed. */
1978 if (move_insn)
1980 byte <<= 6;
1981 number_to_chars_bigendian (f, byte, 1);
1982 fix_new (frag_now, f - frag_now->fr_literal, 1,
1983 op->exp.X_add_symbol, op->exp.X_add_number, 0, BFD_RELOC_M68HC12_5B);
1984 return 1;
1986 else
1988 number_to_chars_bigendian (f, byte, 1);
1989 frag_var (rs_machine_dependent, 2, 2,
1990 ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_UNDF),
1991 op->exp.X_add_symbol,
1992 op->exp.X_add_number, f);
1995 return 3;
1998 if (mode & (M6812_OP_REG | M6812_OP_D_IDX))
2000 if (mode & M6812_OP_D_IDX)
2002 if (op->reg1 != REG_D)
2003 as_bad (_("Expecting register D for indexed indirect mode."));
2004 if (move_insn)
2005 as_bad (_("Indexed indirect mode is not allowed for movb/movw."));
2007 byte = 0xE7;
2009 else
2011 switch (op->reg1)
2013 case REG_A:
2014 byte = 0xE4;
2015 break;
2017 case REG_B:
2018 byte = 0xE5;
2019 break;
2021 default:
2022 as_bad (_("Invalid accumulator register."));
2024 case REG_D:
2025 byte = 0xE6;
2026 break;
2029 switch (op->reg2)
2031 case REG_X:
2032 break;
2034 case REG_Y:
2035 byte |= (1 << 3);
2036 break;
2038 case REG_SP:
2039 byte |= (2 << 3);
2040 break;
2042 case REG_PC:
2043 byte |= (3 << 3);
2044 break;
2046 default:
2047 as_bad (_("Invalid indexed register."));
2048 break;
2050 f = frag_more (1);
2051 number_to_chars_bigendian (f, byte, 1);
2052 return 1;
2055 as_fatal (_("Addressing mode not implemented yet."));
2056 return 0;
2059 /* Assemble the 68HC12 register mode byte. */
2060 static int
2061 build_reg_mode (operand *op, int format)
2063 unsigned char byte;
2064 char *f;
2066 if (format & M6812_OP_SEX_MARKER
2067 && op->reg1 != REG_A && op->reg1 != REG_B && op->reg1 != REG_CCR)
2068 as_bad (_("Invalid source register for this instruction, use 'tfr'."));
2069 else if (op->reg1 == REG_NONE || op->reg1 == REG_PC)
2070 as_bad (_("Invalid source register."));
2072 if (format & M6812_OP_SEX_MARKER
2073 && op->reg2 != REG_D
2074 && op->reg2 != REG_X && op->reg2 != REG_Y && op->reg2 != REG_SP)
2075 as_bad (_("Invalid destination register for this instruction, use 'tfr'."));
2076 else if (op->reg2 == REG_NONE || op->reg2 == REG_PC)
2077 as_bad (_("Invalid destination register."));
2079 byte = (op->reg1 << 4) | (op->reg2);
2080 if (format & M6812_OP_EXG_MARKER)
2081 byte |= 0x80;
2083 f = frag_more (1);
2084 number_to_chars_bigendian (f, byte, 1);
2085 return 1;
2088 /* build_insn takes a pointer to the opcode entry in the opcode table,
2089 the array of operand expressions and builds the corresponding instruction.
2090 This operation only deals with non relative jumps insn (need special
2091 handling). */
2092 static void
2093 build_insn (struct m68hc11_opcode *opcode, operand operands[],
2094 int nb_operands ATTRIBUTE_UNUSED)
2096 int i;
2097 char *f;
2098 long format;
2099 int move_insn = 0;
2101 /* Put the page code instruction if there is one. */
2102 format = opcode->format;
2104 if (format & M6811_OP_BRANCH)
2105 fix_new (frag_now, frag_now_fix (), 0,
2106 &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
2108 if (format & OP_EXTENDED)
2110 int page_code;
2112 f = m68hc11_new_insn (2);
2113 if (format & M6811_OP_PAGE2)
2114 page_code = M6811_OPCODE_PAGE2;
2115 else if (format & M6811_OP_PAGE3)
2116 page_code = M6811_OPCODE_PAGE3;
2117 else
2118 page_code = M6811_OPCODE_PAGE4;
2120 number_to_chars_bigendian (f, page_code, 1);
2121 f++;
2123 else
2124 f = m68hc11_new_insn (1);
2126 number_to_chars_bigendian (f, opcode->opcode, 1);
2128 i = 0;
2130 /* The 68HC12 movb and movw instructions are special. We have to handle
2131 them in a special way. */
2132 if (format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2))
2134 move_insn = 1;
2135 if (format & M6812_OP_IDX)
2137 build_indexed_byte (&operands[0], format, 1);
2138 i = 1;
2139 format &= ~M6812_OP_IDX;
2141 if (format & M6812_OP_IDX_P2)
2143 build_indexed_byte (&operands[1], format, 1);
2144 i = 0;
2145 format &= ~M6812_OP_IDX_P2;
2149 if (format & (M6811_OP_DIRECT | M6811_OP_IMM8))
2151 fixup8 (&operands[i].exp,
2152 format & (M6811_OP_DIRECT | M6811_OP_IMM8 | M6812_OP_TRAP_ID),
2153 operands[i].mode);
2154 i++;
2156 else if (IS_CALL_SYMBOL (format) && nb_operands == 1)
2158 format &= ~M6812_OP_PAGE;
2159 fixup24 (&operands[i].exp, format & M6811_OP_IND16,
2160 operands[i].mode);
2161 i++;
2163 else if (format & (M6811_OP_IMM16 | M6811_OP_IND16))
2165 fixup16 (&operands[i].exp,
2166 format & (M6811_OP_IMM16 | M6811_OP_IND16 | M6812_OP_PAGE),
2167 operands[i].mode);
2168 i++;
2170 else if (format & (M6811_OP_IX | M6811_OP_IY))
2172 if ((format & M6811_OP_IX) && (operands[0].reg1 != REG_X))
2173 as_bad (_("Invalid indexed register, expecting register X."));
2174 if ((format & M6811_OP_IY) && (operands[0].reg1 != REG_Y))
2175 as_bad (_("Invalid indexed register, expecting register Y."));
2177 fixup8 (&operands[0].exp, M6811_OP_IX, operands[0].mode);
2178 i = 1;
2180 else if (format &
2181 (M6812_OP_IDX | M6812_OP_IDX_2 | M6812_OP_IDX_1
2182 | M6812_OP_D_IDX | M6812_OP_D_IDX_2))
2184 build_indexed_byte (&operands[i], format, move_insn);
2185 i++;
2187 else if (format & M6812_OP_REG && current_architecture & cpu6812)
2189 build_reg_mode (&operands[i], format);
2190 i++;
2192 if (format & M6811_OP_BITMASK)
2194 fixup8 (&operands[i].exp, M6811_OP_BITMASK, operands[i].mode);
2195 i++;
2197 if (format & M6811_OP_JUMP_REL)
2199 fixup8 (&operands[i].exp, M6811_OP_JUMP_REL, operands[i].mode);
2201 else if (format & M6812_OP_IND16_P2)
2203 fixup16 (&operands[1].exp, M6811_OP_IND16, operands[1].mode);
2205 if (format & M6812_OP_PAGE)
2207 fixup8 (&operands[i].exp, M6812_OP_PAGE, operands[i].mode);
2211 /* Opcode identification and operand analysis. */
2213 /* find() gets a pointer to an entry in the opcode table. It must look at all
2214 opcodes with the same name and use the operands to choose the correct
2215 opcode. Returns the opcode pointer if there was a match and 0 if none. */
2216 static struct m68hc11_opcode *
2217 find (struct m68hc11_opcode_def *opc, operand operands[], int nb_operands)
2219 int i, match, pos;
2220 struct m68hc11_opcode *opcode;
2221 struct m68hc11_opcode *op_indirect;
2223 op_indirect = 0;
2224 opcode = opc->opcode;
2226 /* Now search the opcode table table for one with operands
2227 that matches what we've got. We're only done if the operands matched so
2228 far AND there are no more to check. */
2229 for (pos = match = 0; match == 0 && pos < opc->nb_modes; pos++, opcode++)
2231 int poss_indirect = 0;
2232 long format = opcode->format;
2233 int expect;
2235 expect = 0;
2236 if (opcode->format & M6811_OP_MASK)
2237 expect++;
2238 if (opcode->format & M6811_OP_BITMASK)
2239 expect++;
2240 if (opcode->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
2241 expect++;
2242 if (opcode->format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2))
2243 expect++;
2244 if ((opcode->format & M6812_OP_PAGE)
2245 && (!IS_CALL_SYMBOL (opcode->format) || nb_operands == 2))
2246 expect++;
2248 for (i = 0; expect == nb_operands && i < nb_operands; i++)
2250 int mode = operands[i].mode;
2252 if (mode & M6811_OP_IMM16)
2254 if (format &
2255 (M6811_OP_IMM8 | M6811_OP_IMM16 | M6811_OP_BITMASK))
2256 continue;
2257 break;
2259 if (mode == M6811_OP_DIRECT)
2261 if (format & M6811_OP_DIRECT)
2262 continue;
2264 /* If the operand is a page 0 operand, remember a
2265 possible <abs-16> addressing mode. We mark
2266 this and continue to check other operands. */
2267 if (format & M6811_OP_IND16
2268 && flag_strict_direct_addressing && op_indirect == 0)
2270 poss_indirect = 1;
2271 continue;
2273 break;
2275 if (mode & M6811_OP_IND16)
2277 if (i == 0 && (format & M6811_OP_IND16) != 0)
2278 continue;
2279 if (i != 0 && (format & M6812_OP_PAGE) != 0)
2280 continue;
2281 if (i != 0 && (format & M6812_OP_IND16_P2) != 0)
2282 continue;
2283 if (i == 0 && (format & M6811_OP_BITMASK))
2284 break;
2286 if (mode & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
2288 if (format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
2289 continue;
2291 if (mode & M6812_OP_REG)
2293 if (i == 0
2294 && (format & M6812_OP_REG)
2295 && (operands[i].reg2 == REG_NONE))
2296 continue;
2297 if (i == 0
2298 && (format & M6812_OP_REG)
2299 && (format & M6812_OP_REG_2)
2300 && (operands[i].reg2 != REG_NONE))
2301 continue;
2302 if (i == 0
2303 && (format & M6812_OP_IDX)
2304 && (operands[i].reg2 != REG_NONE))
2305 continue;
2306 if (i == 0
2307 && (format & M6812_OP_IDX)
2308 && (format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2)))
2309 continue;
2310 if (i == 1
2311 && (format & M6812_OP_IDX_P2))
2312 continue;
2313 break;
2315 if (mode & M6812_OP_IDX)
2317 if (format & M6811_OP_IX && operands[i].reg1 == REG_X)
2318 continue;
2319 if (format & M6811_OP_IY && operands[i].reg1 == REG_Y)
2320 continue;
2321 if (i == 0
2322 && format & (M6812_OP_IDX | M6812_OP_IDX_1 | M6812_OP_IDX_2)
2323 && (operands[i].reg1 == REG_X
2324 || operands[i].reg1 == REG_Y
2325 || operands[i].reg1 == REG_SP
2326 || operands[i].reg1 == REG_PC))
2327 continue;
2328 if (i == 1 && format & M6812_OP_IDX_P2)
2329 continue;
2331 if (mode & format & (M6812_OP_D_IDX | M6812_OP_D_IDX_2))
2333 if (i == 0)
2334 continue;
2336 if (mode & M6812_AUTO_INC_DEC)
2338 if (i == 0
2339 && format & (M6812_OP_IDX | M6812_OP_IDX_1 |
2340 M6812_OP_IDX_2))
2341 continue;
2342 if (i == 1 && format & M6812_OP_IDX_P2)
2343 continue;
2345 break;
2347 match = i == nb_operands;
2349 /* Operands are ok but an operand uses page 0 addressing mode
2350 while the insn supports abs-16 mode. Keep a reference to this
2351 insns in case there is no insn supporting page 0 addressing. */
2352 if (match && poss_indirect)
2354 op_indirect = opcode;
2355 match = 0;
2357 if (match)
2358 break;
2361 /* Page 0 addressing is used but not supported by any insn.
2362 If absolute addresses are supported, we use that insn. */
2363 if (match == 0 && op_indirect)
2365 opcode = op_indirect;
2366 match = 1;
2369 if (!match)
2371 return (0);
2374 return opcode;
2377 /* Find the real opcode and its associated operands. We use a progressive
2378 approach here. On entry, 'opc' points to the first opcode in the
2379 table that matches the opcode name in the source line. We try to
2380 isolate an operand, find a possible match in the opcode table.
2381 We isolate another operand if no match were found. The table 'operands'
2382 is filled while operands are recognized.
2384 Returns the opcode pointer that matches the opcode name in the
2385 source line and the associated operands. */
2386 static struct m68hc11_opcode *
2387 find_opcode (struct m68hc11_opcode_def *opc, operand operands[],
2388 int *nb_operands)
2390 struct m68hc11_opcode *opcode;
2391 int i;
2393 if (opc->max_operands == 0)
2395 *nb_operands = 0;
2396 return opc->opcode;
2399 for (i = 0; i < opc->max_operands;)
2401 int result;
2403 result = get_operand (&operands[i], i, opc->format);
2404 if (result <= 0)
2405 return 0;
2407 /* Special case where the bitmask of the bclr/brclr
2408 instructions is not introduced by #.
2409 Example: bclr 3,x $80. */
2410 if (i == 1 && (opc->format & M6811_OP_BITMASK)
2411 && (operands[i].mode & M6811_OP_IND16))
2413 operands[i].mode = M6811_OP_IMM16;
2416 i += result;
2417 *nb_operands = i;
2418 if (i >= opc->min_operands)
2420 opcode = find (opc, operands, i);
2422 /* Another special case for 'call foo,page' instructions.
2423 Since we support 'call foo' and 'call foo,page' we must look
2424 if the optional page specification is present otherwise we will
2425 assemble immediately and treat the page spec as garbage. */
2426 if (opcode && !(opcode->format & M6812_OP_PAGE))
2427 return opcode;
2429 if (opcode && *input_line_pointer != ',')
2430 return opcode;
2433 if (*input_line_pointer == ',')
2434 input_line_pointer++;
2437 return 0;
2440 #define M6812_XBCC_MARKER (M6812_OP_TBCC_MARKER \
2441 | M6812_OP_DBCC_MARKER \
2442 | M6812_OP_IBCC_MARKER)
2444 /* Gas line assembler entry point. */
2446 /* This is the main entry point for the machine-dependent assembler. str
2447 points to a machine-dependent instruction. This function is supposed to
2448 emit the frags/bytes it assembles to. */
2449 void
2450 md_assemble (char *str)
2452 struct m68hc11_opcode_def *opc;
2453 struct m68hc11_opcode *opcode;
2455 unsigned char *op_start, *op_end;
2456 char *save;
2457 char name[20];
2458 int nlen = 0;
2459 operand operands[M6811_MAX_OPERANDS];
2460 int nb_operands = 0;
2461 int branch_optimize = 0;
2462 int alias_id = -1;
2464 /* Drop leading whitespace. */
2465 while (*str == ' ')
2466 str++;
2468 /* Find the opcode end and get the opcode in 'name'. The opcode is forced
2469 lower case (the opcode table only has lower case op-codes). */
2470 for (op_start = op_end = (unsigned char *) str;
2471 *op_end && nlen < 20 && !is_end_of_line[*op_end] && *op_end != ' ';
2472 op_end++)
2474 name[nlen] = TOLOWER (op_start[nlen]);
2475 nlen++;
2477 name[nlen] = 0;
2479 if (nlen == 0)
2481 as_bad (_("No instruction or missing opcode."));
2482 return;
2485 /* Find the opcode definition given its name. */
2486 opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash, name);
2488 /* If it's not recognized, look for 'jbsr' and 'jbxx'. These are
2489 pseudo insns for relative branch. For these branches, we always
2490 optimize them (turned into absolute branches) even if --short-branches
2491 is given. */
2492 if (opc == NULL && name[0] == 'j' && name[1] == 'b')
2494 opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash, &name[1]);
2495 if (opc
2496 && (!(opc->format & M6811_OP_JUMP_REL)
2497 || (opc->format & M6811_OP_BITMASK)))
2498 opc = 0;
2499 if (opc)
2500 branch_optimize = 1;
2503 /* The following test should probably be removed. This is not conform
2504 to Motorola assembler specs. */
2505 if (opc == NULL && flag_mri)
2507 if (*op_end == ' ' || *op_end == '\t')
2509 while (*op_end == ' ' || *op_end == '\t')
2510 op_end++;
2512 if (nlen < 19
2513 && (*op_end &&
2514 (is_end_of_line[op_end[1]]
2515 || op_end[1] == ' ' || op_end[1] == '\t'
2516 || !ISALNUM (op_end[1])))
2517 && (*op_end == 'a' || *op_end == 'b'
2518 || *op_end == 'A' || *op_end == 'B'
2519 || *op_end == 'd' || *op_end == 'D'
2520 || *op_end == 'x' || *op_end == 'X'
2521 || *op_end == 'y' || *op_end == 'Y'))
2523 name[nlen++] = TOLOWER (*op_end++);
2524 name[nlen] = 0;
2525 opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash,
2526 name);
2531 /* Identify a possible instruction alias. There are some on the
2532 68HC12 to emulate a few 68HC11 instructions. */
2533 if (opc == NULL && (current_architecture & cpu6812))
2535 int i;
2537 for (i = 0; i < m68hc12_num_alias; i++)
2538 if (strcmp (m68hc12_alias[i].name, name) == 0)
2540 alias_id = i;
2541 break;
2544 if (opc == NULL && alias_id < 0)
2546 as_bad (_("Opcode `%s' is not recognized."), name);
2547 return;
2549 save = input_line_pointer;
2550 input_line_pointer = (char *) op_end;
2552 if (opc)
2554 opc->used++;
2555 opcode = find_opcode (opc, operands, &nb_operands);
2557 else
2558 opcode = 0;
2560 if ((opcode || alias_id >= 0) && !flag_mri)
2562 char *p = input_line_pointer;
2564 while (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r')
2565 p++;
2567 if (*p != '\n' && *p)
2568 as_bad (_("Garbage at end of instruction: `%s'."), p);
2571 input_line_pointer = save;
2573 if (alias_id >= 0)
2575 char *f = m68hc11_new_insn (m68hc12_alias[alias_id].size);
2577 number_to_chars_bigendian (f, m68hc12_alias[alias_id].code1, 1);
2578 if (m68hc12_alias[alias_id].size > 1)
2579 number_to_chars_bigendian (f + 1, m68hc12_alias[alias_id].code2, 1);
2581 return;
2584 /* Opcode is known but does not have valid operands. Print out the
2585 syntax for this opcode. */
2586 if (opcode == 0)
2588 if (flag_print_insn_syntax)
2589 print_insn_format (name);
2591 as_bad (_("Invalid operand for `%s'"), name);
2592 return;
2595 /* Treat dbeq/ibeq/tbeq instructions in a special way. The branch is
2596 relative and must be in the range -256..255 (9-bits). */
2597 if ((opcode->format & M6812_XBCC_MARKER)
2598 && (opcode->format & M6811_OP_JUMP_REL))
2599 build_dbranch_insn (opcode, operands, nb_operands, branch_optimize);
2601 /* Relative jumps instructions are taken care of separately. We have to make
2602 sure that the relative branch is within the range -128..127. If it's out
2603 of range, the instructions are changed into absolute instructions.
2604 This is not supported for the brset and brclr instructions. */
2605 else if ((opcode->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
2606 && !(opcode->format & M6811_OP_BITMASK))
2607 build_jump_insn (opcode, operands, nb_operands, branch_optimize);
2608 else
2609 build_insn (opcode, operands, nb_operands);
2613 /* Pseudo op to control the ELF flags. */
2614 static void
2615 s_m68hc11_mode (int x ATTRIBUTE_UNUSED)
2617 char *name = input_line_pointer, ch;
2619 while (!is_end_of_line[(unsigned char) *input_line_pointer])
2620 input_line_pointer++;
2621 ch = *input_line_pointer;
2622 *input_line_pointer = '\0';
2624 if (strcmp (name, "mshort") == 0)
2626 elf_flags &= ~E_M68HC11_I32;
2628 else if (strcmp (name, "mlong") == 0)
2630 elf_flags |= E_M68HC11_I32;
2632 else if (strcmp (name, "mshort-double") == 0)
2634 elf_flags &= ~E_M68HC11_F64;
2636 else if (strcmp (name, "mlong-double") == 0)
2638 elf_flags |= E_M68HC11_F64;
2640 else
2642 as_warn (_("Invalid mode: %s\n"), name);
2644 *input_line_pointer = ch;
2645 demand_empty_rest_of_line ();
2648 /* Mark the symbols with STO_M68HC12_FAR to indicate the functions
2649 are using 'rtc' for returning. It is necessary to use 'call'
2650 to invoke them. This is also used by the debugger to correctly
2651 find the stack frame. */
2652 static void
2653 s_m68hc11_mark_symbol (int mark)
2655 char *name;
2656 int c;
2657 symbolS *symbolP;
2658 asymbol *bfdsym;
2659 elf_symbol_type *elfsym;
2663 name = input_line_pointer;
2664 c = get_symbol_end ();
2665 symbolP = symbol_find_or_make (name);
2666 *input_line_pointer = c;
2668 SKIP_WHITESPACE ();
2670 bfdsym = symbol_get_bfdsym (symbolP);
2671 elfsym = elf_symbol_from (bfd_asymbol_bfd (bfdsym), bfdsym);
2673 assert (elfsym);
2675 /* Mark the symbol far (using rtc for function return). */
2676 elfsym->internal_elf_sym.st_other |= mark;
2678 if (c == ',')
2680 input_line_pointer ++;
2682 SKIP_WHITESPACE ();
2684 if (*input_line_pointer == '\n')
2685 c = '\n';
2688 while (c == ',');
2690 demand_empty_rest_of_line ();
2693 static void
2694 s_m68hc11_relax (int ignore ATTRIBUTE_UNUSED)
2696 expressionS ex;
2698 expression (&ex);
2700 if (ex.X_op != O_symbol || ex.X_add_number != 0)
2702 as_bad (_("bad .relax format"));
2703 ignore_rest_of_line ();
2704 return;
2707 fix_new_exp (frag_now, frag_now_fix (), 0, &ex, 1,
2708 BFD_RELOC_M68HC11_RL_GROUP);
2710 demand_empty_rest_of_line ();
2714 /* Relocation, relaxation and frag conversions. */
2716 /* PC-relative offsets are relative to the start of the
2717 next instruction. That is, the address of the offset, plus its
2718 size, since the offset is always the last part of the insn. */
2719 long
2720 md_pcrel_from (fixS *fixP)
2722 if (fixP->fx_r_type == BFD_RELOC_M68HC11_RL_JUMP)
2723 return 0;
2725 return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
2728 /* If while processing a fixup, a reloc really needs to be created
2729 then it is done here. */
2730 arelent *
2731 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
2733 arelent *reloc;
2735 reloc = (arelent *) xmalloc (sizeof (arelent));
2736 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
2737 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
2738 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
2739 if (fixp->fx_r_type == 0)
2740 reloc->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_16);
2741 else
2742 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
2743 if (reloc->howto == (reloc_howto_type *) NULL)
2745 as_bad_where (fixp->fx_file, fixp->fx_line,
2746 _("Relocation %d is not supported by object file format."),
2747 (int) fixp->fx_r_type);
2748 return NULL;
2751 /* Since we use Rel instead of Rela, encode the vtable entry to be
2752 used in the relocation's section offset. */
2753 if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
2754 reloc->address = fixp->fx_offset;
2756 reloc->addend = 0;
2757 return reloc;
2760 /* We need a port-specific relaxation function to cope with sym2 - sym1
2761 relative expressions with both symbols in the same segment (but not
2762 necessarily in the same frag as this insn), for example:
2763 ldab sym2-(sym1-2),pc
2764 sym1:
2765 The offset can be 5, 9 or 16 bits long. */
2767 long
2768 m68hc11_relax_frag (segT seg ATTRIBUTE_UNUSED, fragS *fragP,
2769 long stretch ATTRIBUTE_UNUSED)
2771 long growth;
2772 offsetT aim = 0;
2773 symbolS *symbolP;
2774 const relax_typeS *this_type;
2775 const relax_typeS *start_type;
2776 relax_substateT next_state;
2777 relax_substateT this_state;
2778 const relax_typeS *table = TC_GENERIC_RELAX_TABLE;
2780 /* We only have to cope with frags as prepared by
2781 md_estimate_size_before_relax. The STATE_BITS16 case may geet here
2782 because of the different reasons that it's not relaxable. */
2783 switch (fragP->fr_subtype)
2785 case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS16):
2786 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16):
2787 /* When we get to this state, the frag won't grow any more. */
2788 return 0;
2790 case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS5):
2791 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS5):
2792 case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS9):
2793 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9):
2794 if (fragP->fr_symbol == NULL
2795 || S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
2796 as_fatal (_("internal inconsistency problem in %s: fr_symbol %lx"),
2797 __FUNCTION__, (long) fragP->fr_symbol);
2798 symbolP = fragP->fr_symbol;
2799 if (symbol_resolved_p (symbolP))
2800 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
2801 __FUNCTION__);
2802 aim = S_GET_VALUE (symbolP);
2803 break;
2805 default:
2806 as_fatal (_("internal inconsistency problem in %s: fr_subtype %d"),
2807 __FUNCTION__, fragP->fr_subtype);
2810 /* The rest is stolen from relax_frag. There's no obvious way to
2811 share the code, but fortunately no requirement to keep in sync as
2812 long as fragP->fr_symbol does not have its segment changed. */
2814 this_state = fragP->fr_subtype;
2815 start_type = this_type = table + this_state;
2817 if (aim < 0)
2819 /* Look backwards. */
2820 for (next_state = this_type->rlx_more; next_state;)
2821 if (aim >= this_type->rlx_backward)
2822 next_state = 0;
2823 else
2825 /* Grow to next state. */
2826 this_state = next_state;
2827 this_type = table + this_state;
2828 next_state = this_type->rlx_more;
2831 else
2833 /* Look forwards. */
2834 for (next_state = this_type->rlx_more; next_state;)
2835 if (aim <= this_type->rlx_forward)
2836 next_state = 0;
2837 else
2839 /* Grow to next state. */
2840 this_state = next_state;
2841 this_type = table + this_state;
2842 next_state = this_type->rlx_more;
2846 growth = this_type->rlx_length - start_type->rlx_length;
2847 if (growth != 0)
2848 fragP->fr_subtype = this_state;
2849 return growth;
2852 void
2853 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, asection *sec ATTRIBUTE_UNUSED,
2854 fragS *fragP)
2856 fixS *fixp;
2857 long value;
2858 long disp;
2859 char *buffer_address = fragP->fr_literal;
2861 /* Address in object code of the displacement. */
2862 register int object_address = fragP->fr_fix + fragP->fr_address;
2864 buffer_address += fragP->fr_fix;
2866 /* The displacement of the address, from current location. */
2867 value = S_GET_VALUE (fragP->fr_symbol);
2868 disp = (value + fragP->fr_offset) - object_address;
2870 switch (fragP->fr_subtype)
2872 case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE):
2873 fragP->fr_opcode[1] = disp;
2874 break;
2876 case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD):
2877 /* This relax is only for bsr and bra. */
2878 assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
2879 || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
2880 || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
2882 fragP->fr_opcode[0] = convert_branch (fragP->fr_opcode[0]);
2884 fix_new (fragP, fragP->fr_fix - 1, 2,
2885 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
2886 fragP->fr_fix += 1;
2887 break;
2889 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_BYTE):
2890 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_BYTE):
2891 fragP->fr_opcode[1] = disp;
2892 break;
2894 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_WORD):
2895 /* Invert branch. */
2896 fragP->fr_opcode[0] ^= 1;
2897 fragP->fr_opcode[1] = 3; /* Branch offset. */
2898 buffer_address[0] = M6811_JMP;
2899 fix_new (fragP, fragP->fr_fix + 1, 2,
2900 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
2901 fragP->fr_fix += 3;
2902 break;
2904 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_WORD):
2905 /* Translate branch into a long branch. */
2906 fragP->fr_opcode[1] = fragP->fr_opcode[0];
2907 fragP->fr_opcode[0] = M6811_OPCODE_PAGE2;
2909 fixp = fix_new (fragP, fragP->fr_fix, 2,
2910 fragP->fr_symbol, fragP->fr_offset, 1,
2911 BFD_RELOC_16_PCREL);
2912 fixp->fx_pcrel_adjust = 2;
2913 fragP->fr_fix += 2;
2914 break;
2916 case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS5):
2917 if (fragP->fr_symbol != 0
2918 && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
2919 value = disp;
2920 /* fall through */
2922 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS5):
2923 fragP->fr_opcode[0] = fragP->fr_opcode[0] << 6;
2924 fragP->fr_opcode[0] |= value & 0x1f;
2925 break;
2927 case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS9):
2928 /* For a PC-relative offset, use the displacement with a -1 correction
2929 to take into account the additional byte of the insn. */
2930 if (fragP->fr_symbol != 0
2931 && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
2932 value = disp - 1;
2933 /* fall through */
2935 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9):
2936 fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3);
2937 fragP->fr_opcode[0] |= 0xE0;
2938 fragP->fr_opcode[0] |= (value >> 8) & 1;
2939 fragP->fr_opcode[1] = value;
2940 fragP->fr_fix += 1;
2941 break;
2943 case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS16):
2944 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16):
2945 fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3);
2946 fragP->fr_opcode[0] |= 0xe2;
2947 if ((fragP->fr_opcode[0] & 0x0ff) == 0x0fa
2948 && fragP->fr_symbol != 0
2949 && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
2951 fixp = fix_new (fragP, fragP->fr_fix, 2,
2952 fragP->fr_symbol, fragP->fr_offset,
2953 1, BFD_RELOC_16_PCREL);
2955 else
2957 fix_new (fragP, fragP->fr_fix, 2,
2958 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
2960 fragP->fr_fix += 2;
2961 break;
2963 case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_BYTE):
2964 if (disp < 0)
2965 fragP->fr_opcode[0] |= 0x10;
2967 fragP->fr_opcode[1] = disp & 0x0FF;
2968 break;
2970 case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_WORD):
2971 /* Invert branch. */
2972 fragP->fr_opcode[0] ^= 0x20;
2973 fragP->fr_opcode[1] = 3; /* Branch offset. */
2974 buffer_address[0] = M6812_JMP;
2975 fix_new (fragP, fragP->fr_fix + 1, 2,
2976 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
2977 fragP->fr_fix += 3;
2978 break;
2980 default:
2981 break;
2985 /* On an ELF system, we can't relax a weak symbol. The weak symbol
2986 can be overridden at final link time by a non weak symbol. We can
2987 relax externally visible symbol because there is no shared library
2988 and such symbol can't be overridden (unless they are weak). */
2989 static int
2990 relaxable_symbol (symbolS *symbol)
2992 return ! S_IS_WEAK (symbol);
2995 /* Force truly undefined symbols to their maximum size, and generally set up
2996 the frag list to be relaxed. */
2998 md_estimate_size_before_relax (fragS *fragP, asection *segment)
3000 if (RELAX_LENGTH (fragP->fr_subtype) == STATE_UNDF)
3002 if (S_GET_SEGMENT (fragP->fr_symbol) != segment
3003 || !relaxable_symbol (fragP->fr_symbol)
3004 || (segment != absolute_section
3005 && RELAX_STATE (fragP->fr_subtype) == STATE_INDEXED_OFFSET))
3007 /* Non-relaxable cases. */
3008 int old_fr_fix;
3009 char *buffer_address;
3011 old_fr_fix = fragP->fr_fix;
3012 buffer_address = fragP->fr_fix + fragP->fr_literal;
3014 switch (RELAX_STATE (fragP->fr_subtype))
3016 case STATE_PC_RELATIVE:
3018 /* This relax is only for bsr and bra. */
3019 assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
3020 || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
3021 || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
3023 if (flag_fixed_branches)
3024 as_bad_where (fragP->fr_file, fragP->fr_line,
3025 _("bra or bsr with undefined symbol."));
3027 /* The symbol is undefined or in a separate section.
3028 Turn bra into a jmp and bsr into a jsr. The insn
3029 becomes 3 bytes long (instead of 2). A fixup is
3030 necessary for the unresolved symbol address. */
3031 fragP->fr_opcode[0] = convert_branch (fragP->fr_opcode[0]);
3033 fix_new (fragP, fragP->fr_fix - 1, 2, fragP->fr_symbol,
3034 fragP->fr_offset, 0, BFD_RELOC_16);
3035 fragP->fr_fix++;
3036 break;
3038 case STATE_CONDITIONAL_BRANCH:
3039 assert (current_architecture & cpu6811);
3041 fragP->fr_opcode[0] ^= 1; /* Reverse sense of branch. */
3042 fragP->fr_opcode[1] = 3; /* Skip next jmp insn (3 bytes). */
3044 /* Don't use fr_opcode[2] because this may be
3045 in a different frag. */
3046 buffer_address[0] = M6811_JMP;
3048 fragP->fr_fix++;
3049 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
3050 fragP->fr_offset, 0, BFD_RELOC_16);
3051 fragP->fr_fix += 2;
3052 break;
3054 case STATE_INDEXED_OFFSET:
3055 assert (current_architecture & cpu6812);
3057 if (fragP->fr_symbol
3058 && S_GET_SEGMENT (fragP->fr_symbol) == absolute_section)
3060 fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_OFFSET,
3061 STATE_BITS5);
3062 /* Return the size of the variable part of the frag. */
3063 return md_relax_table[fragP->fr_subtype].rlx_length;
3065 else
3067 /* Switch the indexed operation to 16-bit mode. */
3068 fragP->fr_opcode[0] = fragP->fr_opcode[0] << 3;
3069 fragP->fr_opcode[0] |= 0xe2;
3070 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
3071 fragP->fr_offset, 0, BFD_RELOC_16);
3072 fragP->fr_fix += 2;
3074 break;
3076 case STATE_INDEXED_PCREL:
3077 assert (current_architecture & cpu6812);
3079 if (fragP->fr_symbol
3080 && S_GET_SEGMENT (fragP->fr_symbol) == absolute_section)
3082 fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_PCREL,
3083 STATE_BITS5);
3084 /* Return the size of the variable part of the frag. */
3085 return md_relax_table[fragP->fr_subtype].rlx_length;
3087 else
3089 fixS* fixp;
3091 fragP->fr_opcode[0] = fragP->fr_opcode[0] << 3;
3092 fragP->fr_opcode[0] |= 0xe2;
3093 fixp = fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
3094 fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
3095 fragP->fr_fix += 2;
3097 break;
3099 case STATE_XBCC_BRANCH:
3100 assert (current_architecture & cpu6812);
3102 fragP->fr_opcode[0] ^= 0x20; /* Reverse sense of branch. */
3103 fragP->fr_opcode[1] = 3; /* Skip next jmp insn (3 bytes). */
3105 /* Don't use fr_opcode[2] because this may be
3106 in a different frag. */
3107 buffer_address[0] = M6812_JMP;
3109 fragP->fr_fix++;
3110 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
3111 fragP->fr_offset, 0, BFD_RELOC_16);
3112 fragP->fr_fix += 2;
3113 break;
3115 case STATE_CONDITIONAL_BRANCH_6812:
3116 assert (current_architecture & cpu6812);
3118 /* Translate into a lbcc branch. */
3119 fragP->fr_opcode[1] = fragP->fr_opcode[0];
3120 fragP->fr_opcode[0] = M6811_OPCODE_PAGE2;
3122 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
3123 fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
3124 fragP->fr_fix += 2;
3125 break;
3127 default:
3128 as_fatal (_("Subtype %d is not recognized."), fragP->fr_subtype);
3130 frag_wane (fragP);
3132 /* Return the growth in the fixed part of the frag. */
3133 return fragP->fr_fix - old_fr_fix;
3136 /* Relaxable cases. */
3137 switch (RELAX_STATE (fragP->fr_subtype))
3139 case STATE_PC_RELATIVE:
3140 /* This relax is only for bsr and bra. */
3141 assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
3142 || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
3143 || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
3145 fragP->fr_subtype = ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE);
3146 break;
3148 case STATE_CONDITIONAL_BRANCH:
3149 assert (current_architecture & cpu6811);
3151 fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH,
3152 STATE_BYTE);
3153 break;
3155 case STATE_INDEXED_OFFSET:
3156 assert (current_architecture & cpu6812);
3158 fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_OFFSET,
3159 STATE_BITS5);
3160 break;
3162 case STATE_INDEXED_PCREL:
3163 assert (current_architecture & cpu6812);
3165 fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_PCREL,
3166 STATE_BITS5);
3167 break;
3169 case STATE_XBCC_BRANCH:
3170 assert (current_architecture & cpu6812);
3172 fragP->fr_subtype = ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_BYTE);
3173 break;
3175 case STATE_CONDITIONAL_BRANCH_6812:
3176 assert (current_architecture & cpu6812);
3178 fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812,
3179 STATE_BYTE);
3180 break;
3184 if (fragP->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))
3185 as_fatal (_("Subtype %d is not recognized."), fragP->fr_subtype);
3187 /* Return the size of the variable part of the frag. */
3188 return md_relax_table[fragP->fr_subtype].rlx_length;
3191 /* See whether we need to force a relocation into the output file. */
3193 tc_m68hc11_force_relocation (fixS *fixP)
3195 if (fixP->fx_r_type == BFD_RELOC_M68HC11_RL_GROUP)
3196 return 1;
3198 return generic_force_reloc (fixP);
3201 /* Here we decide which fixups can be adjusted to make them relative
3202 to the beginning of the section instead of the symbol. Basically
3203 we need to make sure that the linker relaxation is done
3204 correctly, so in some cases we force the original symbol to be
3205 used. */
3207 tc_m68hc11_fix_adjustable (fixS *fixP)
3209 switch (fixP->fx_r_type)
3211 /* For the linker relaxation to work correctly, these relocs
3212 need to be on the symbol itself. */
3213 case BFD_RELOC_16:
3214 case BFD_RELOC_M68HC11_RL_JUMP:
3215 case BFD_RELOC_M68HC11_RL_GROUP:
3216 case BFD_RELOC_VTABLE_INHERIT:
3217 case BFD_RELOC_VTABLE_ENTRY:
3218 case BFD_RELOC_32:
3220 /* The memory bank addressing translation also needs the original
3221 symbol. */
3222 case BFD_RELOC_M68HC11_LO16:
3223 case BFD_RELOC_M68HC11_PAGE:
3224 case BFD_RELOC_M68HC11_24:
3225 return 0;
3227 default:
3228 return 1;
3232 void
3233 md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
3235 char *where;
3236 long value = * valP;
3237 int op_type;
3239 if (fixP->fx_addsy == (symbolS *) NULL)
3240 fixP->fx_done = 1;
3242 /* We don't actually support subtracting a symbol. */
3243 if (fixP->fx_subsy != (symbolS *) NULL)
3244 as_bad_where (fixP->fx_file, fixP->fx_line, _("Expression too complex."));
3246 op_type = fixP->fx_r_type;
3248 /* Patch the instruction with the resolved operand. Elf relocation
3249 info will also be generated to take care of linker/loader fixups.
3250 The 68HC11 addresses only 64Kb, we are only concerned by 8 and 16-bit
3251 relocs. BFD_RELOC_8 is basically used for .page0 access (the linker
3252 will warn for overflows). BFD_RELOC_8_PCREL should not be generated
3253 because it's either resolved or turned out into non-relative insns (see
3254 relax table, bcc, bra, bsr transformations)
3256 The BFD_RELOC_32 is necessary for the support of --gstabs. */
3257 where = fixP->fx_frag->fr_literal + fixP->fx_where;
3259 switch (fixP->fx_r_type)
3261 case BFD_RELOC_32:
3262 bfd_putb32 ((bfd_vma) value, (unsigned char *) where);
3263 break;
3265 case BFD_RELOC_24:
3266 case BFD_RELOC_M68HC11_24:
3267 bfd_putb16 ((bfd_vma) (value & 0x0ffff), (unsigned char *) where);
3268 ((bfd_byte*) where)[2] = ((value >> 16) & 0x0ff);
3269 break;
3271 case BFD_RELOC_16:
3272 case BFD_RELOC_16_PCREL:
3273 case BFD_RELOC_M68HC11_LO16:
3274 bfd_putb16 ((bfd_vma) value, (unsigned char *) where);
3275 if (value < -65537 || value > 65535)
3276 as_bad_where (fixP->fx_file, fixP->fx_line,
3277 _("Value out of 16-bit range."));
3278 break;
3280 case BFD_RELOC_M68HC11_HI8:
3281 value = value >> 8;
3282 /* Fall through. */
3284 case BFD_RELOC_M68HC11_LO8:
3285 case BFD_RELOC_8:
3286 case BFD_RELOC_M68HC11_PAGE:
3287 ((bfd_byte *) where)[0] = (bfd_byte) value;
3288 break;
3290 case BFD_RELOC_8_PCREL:
3291 ((bfd_byte *) where)[0] = (bfd_byte) value;
3293 if (value < -128 || value > 127)
3294 as_bad_where (fixP->fx_file, fixP->fx_line,
3295 _("Value %ld too large for 8-bit PC-relative branch."),
3296 value);
3297 break;
3299 case BFD_RELOC_M68HC11_3B:
3300 if (value <= 0 || value > 8)
3301 as_bad_where (fixP->fx_file, fixP->fx_line,
3302 _("Auto increment/decrement offset '%ld' is out of range."),
3303 value);
3304 if (where[0] & 0x8)
3305 value = 8 - value;
3306 else
3307 value--;
3309 where[0] = where[0] | (value & 0x07);
3310 break;
3312 case BFD_RELOC_M68HC12_5B:
3313 if (value < -16 || value > 15)
3314 as_bad_where (fixP->fx_file, fixP->fx_line,
3315 _("Offset out of 5-bit range for movw/movb insn: %ld"),
3316 value);
3317 if (value >= 0)
3318 where[0] |= value;
3319 else
3320 where[0] |= (0x10 | (16 + value));
3321 break;
3323 case BFD_RELOC_M68HC11_RL_JUMP:
3324 case BFD_RELOC_M68HC11_RL_GROUP:
3325 case BFD_RELOC_VTABLE_INHERIT:
3326 case BFD_RELOC_VTABLE_ENTRY:
3327 fixP->fx_done = 0;
3328 return;
3330 default:
3331 as_fatal (_("Line %d: unknown relocation type: 0x%x."),
3332 fixP->fx_line, fixP->fx_r_type);
3336 /* Set the ELF specific flags. */
3337 void
3338 m68hc11_elf_final_processing (void)
3340 if (current_architecture & cpu6812s)
3341 elf_flags |= EF_M68HCS12_MACH;
3342 elf_elfheader (stdoutput)->e_flags &= ~EF_M68HC11_ABI;
3343 elf_elfheader (stdoutput)->e_flags |= elf_flags;