1 /* tc-m68hc11.c -- Assembler code for the Motorola 68HC11 & 68HC12.
2 Copyright (C) 1999, 2000 Free Software Foundation.
3 Written by Stephane Carrez (stcarrez@worldnet.fr)
5 This file is part of GAS, the GNU Assembler.
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
26 #include "opcode/m68hc11.h"
27 #include "dwarf2dbg.h"
29 struct dwarf2_line_info debug_line;
31 const char comment_chars[] = ";!";
32 const char line_comment_chars[] = "#*";
33 const char line_separator_chars[] = "";
35 const char EXP_CHARS[] = "eE";
36 const char FLT_CHARS[] = "dD";
38 #define STATE_CONDITIONAL_BRANCH (1)
39 #define STATE_PC_RELATIVE (2)
40 #define STATE_INDEXED_OFFSET (3)
41 #define STATE_XBCC_BRANCH (4)
42 #define STATE_CONDITIONAL_BRANCH_6812 (5)
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))
55 #define IS_OPCODE(C1,C2) (((C1) & 0x0FF) == ((C2) & 0x0FF))
57 /* This table describes how you change sizes for the various types of variable
58 size expressions. This version only supports two kinds. */
61 How far Forward this mode will reach.
62 How far Backward this mode will reach.
63 How many bytes this mode will add to the size of the frag.
64 Which mode to go to if the offset won't fit in this one. */
66 relax_typeS md_relax_table[] =
68 {1, 1, 0, 0}, /* First entries aren't used. */
69 {1, 1, 0, 0}, /* For no good reason except. */
70 {1, 1, 0, 0}, /* that the VAX doesn't either. */
74 These insns are translated into b!cc +3 jmp L. */
75 {(127), (-128), 0, ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_WORD)},
80 /* Relax for bsr <L> and bra <L>.
81 These insns are translated into jsr and jmp. */
82 {(127), (-128), 0, ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD)},
87 /* Relax for indexed offset: 5-bits, 9-bits, 16-bits. */
88 {(15), (-16), 0, ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9)},
89 {(255), (-256), 1, ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16)},
93 /* Relax for dbeq/ibeq/tbeq r,<L>:
94 These insns are translated into db!cc +3 jmp L. */
95 {(255), (-256), 0, ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_WORD)},
100 /* Relax for bcc <L> on 68HC12.
101 These insns are translated into lbcc <L>. */
102 {(127), (-128), 0, ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_WORD)},
109 /* 68HC11 and 68HC12 registers. They are numbered according to the 68HC12. */
110 typedef enum register_id
123 typedef struct operand
131 struct m68hc11_opcode_def
138 struct m68hc11_opcode *opcode;
141 static struct m68hc11_opcode_def *m68hc11_opcode_defs = 0;
142 static int m68hc11_nb_opcode_defs = 0;
151 static alias alias_opcodes[] =
159 /* Local functions. */
160 static register_id reg_name_search PARAMS ((char *));
161 static register_id register_name PARAMS ((void));
162 static int check_range PARAMS ((long, int));
163 static void print_opcode_list PARAMS ((void));
164 static void get_default_target PARAMS ((void));
165 static void print_insn_format PARAMS ((char *));
166 static int get_operand PARAMS ((operand *, int, long));
167 static void fixup8 PARAMS ((expressionS *, int, int));
168 static void fixup16 PARAMS ((expressionS *, int, int));
169 static struct m68hc11_opcode *find_opcode
170 PARAMS ((struct m68hc11_opcode_def *, operand *, int *));
171 static void build_jump_insn
172 PARAMS ((struct m68hc11_opcode *, operand *, int, int));
173 static void build_insn
174 PARAMS ((struct m68hc11_opcode *, operand *, int));
176 /* Controls whether relative branches can be turned into long branches.
177 When the relative offset is too large, the insn are changed:
185 Setting the flag forbidds this. */
186 static short flag_fixed_branchs = 0;
188 /* Force to use long jumps (absolute) instead of relative branches. */
189 static short flag_force_long_jumps = 0;
191 /* Change the direct addressing mode into an absolute addressing mode
192 when the insn does not support direct addressing.
193 For example, "clr *ZD0" is normally not possible and is changed
195 static short flag_strict_direct_addressing = 1;
197 /* When an opcode has invalid operand, print out the syntax of the opcode
199 static short flag_print_insn_syntax = 0;
201 /* Dumps the list of instructions with syntax and then exit:
202 1 -> Only dumps the list (sorted by name)
203 2 -> Generate an example (or test) that can be compiled. */
204 static short flag_print_opcodes = 0;
206 /* Opcode hash table. */
207 static struct hash_control *m68hc11_hash;
209 /* Current cpu (either cpu6811 or cpu6812). This is determined automagically
210 by 'get_default_target' by looking at default BFD vector. This is overriden
211 with the -m<cpu> option. */
212 static int current_architecture = 0;
214 /* Default cpu determined by 'get_default_target'. */
215 static const char *default_cpu;
217 /* Number of opcodes in the sorted table (filtered by current cpu). */
218 static int num_opcodes;
220 /* The opcodes sorted by name and filtered by current cpu. */
221 static struct m68hc11_opcode *m68hc11_sorted_opcodes;
223 /* These are the machine dependent pseudo-ops. These are included so
224 the assembler can work on the output from the SUN C compiler, which
227 /* This table describes all the machine specific pseudo-ops the assembler
228 has to support. The fields are:
229 pseudo-op name without dot
230 function to call to execute this pseudo-op
231 Integer arg to pass to the function. */
232 const pseudo_typeS md_pseudo_table[] =
234 /* The following pseudo-ops are supported for MRI compatibility. */
237 {"fcc", stringer, 1},
239 {"file", dwarf2_directive_file, 0},
240 {"loc", dwarf2_directive_loc, 0},
245 /* Options and initialization. */
247 CONST char *md_shortopts = "Sm:";
249 struct option md_longopts[] =
251 #define OPTION_FORCE_LONG_BRANCH (OPTION_MD_BASE)
252 {"force-long-branchs", no_argument, NULL, OPTION_FORCE_LONG_BRANCH},
254 #define OPTION_SHORT_BRANCHS (OPTION_MD_BASE + 1)
255 {"short-branchs", no_argument, NULL, OPTION_SHORT_BRANCHS},
257 #define OPTION_STRICT_DIRECT_MODE (OPTION_MD_BASE + 2)
258 {"strict-direct-mode", no_argument, NULL, OPTION_STRICT_DIRECT_MODE},
260 #define OPTION_PRINT_INSN_SYNTAX (OPTION_MD_BASE + 3)
261 {"print-insn-syntax", no_argument, NULL, OPTION_PRINT_INSN_SYNTAX},
263 #define OPTION_PRINT_OPCODES (OPTION_MD_BASE + 4)
264 {"print-opcodes", no_argument, NULL, OPTION_PRINT_OPCODES},
266 #define OPTION_GENERATE_EXAMPLE (OPTION_MD_BASE + 5)
267 {"generate-example", no_argument, NULL, OPTION_GENERATE_EXAMPLE},
269 {NULL, no_argument, NULL, 0}
271 size_t md_longopts_size = sizeof (md_longopts);
273 /* Get the target cpu for the assembler. This is based on the configure
274 options and on the -m68hc11/-m68hc12 option. If no option is specified,
275 we must get the default. */
277 m68hc11_arch_format ()
279 get_default_target ();
280 if (current_architecture & cpu6811)
281 return "elf32-m68hc11";
283 return "elf32-m68hc12";
286 enum bfd_architecture
289 get_default_target ();
290 if (current_architecture & cpu6811)
291 return bfd_arch_m68hc11;
293 return bfd_arch_m68hc12;
303 md_show_usage (stream)
306 get_default_target ();
307 fprintf (stream, _("\
308 Motorola 68HC11/68HC12 options:\n\
309 -m68hc11 | -m68hc12 specify the processor [default %s]\n\
310 --force-long-branchs always turn relative branchs into absolute ones\n\
311 -S,--short-branchs do not turn relative branchs into absolute ones\n\
312 when the offset is out of range\n\
313 --strict-direct-mode do not turn the direct mode into extended mode\n\
314 when the instruction does not support direct mode\n\
315 --print-insn-syntax print the syntax of instruction in case of error\n\
316 --print-opcodes print the list of instructions with syntax\n\
317 --generate-example generate an example of each instruction\n\
318 (used for testing)\n"), default_cpu);
322 /* Try to identify the default target based on the BFD library. */
324 get_default_target ()
326 const bfd_target *target;
329 if (current_architecture != 0)
332 default_cpu = "unknown";
333 target = bfd_find_target (0, &abfd);
334 if (target && target->name)
336 if (strcmp (target->name, "elf32-m68hc12") == 0)
338 current_architecture = cpu6812;
339 default_cpu = "m68hc12";
341 else if (strcmp (target->name, "elf32-m68hc11") == 0)
343 current_architecture = cpu6811;
344 default_cpu = "m68hc11";
348 as_bad (_("Default target `%s' is not supported."), target->name);
354 m68hc11_print_statistics (file)
358 struct m68hc11_opcode_def *opc;
360 hash_print_statistics (file, "opcode table", m68hc11_hash);
362 opc = m68hc11_opcode_defs;
363 if (opc == 0 || m68hc11_nb_opcode_defs == 0)
366 /* Dump the opcode statistics table. */
367 fprintf (file, _("Name # Modes Min ops Max ops Modes mask # Used\n"));
368 for (i = 0; i < m68hc11_nb_opcode_defs; i++, opc++)
370 fprintf (file, "%-7.7s %5d %7d %7d 0x%08lx %7d\n",
373 opc->min_operands, opc->max_operands, opc->format, opc->used);
378 md_parse_option (c, arg)
382 get_default_target ();
385 /* -S means keep external to 2 bits offset rather than 16 bits one. */
386 case OPTION_SHORT_BRANCHS:
388 flag_fixed_branchs = 1;
391 case OPTION_FORCE_LONG_BRANCH:
392 flag_force_long_jumps = 1;
395 case OPTION_PRINT_INSN_SYNTAX:
396 flag_print_insn_syntax = 1;
399 case OPTION_PRINT_OPCODES:
400 flag_print_opcodes = 1;
403 case OPTION_STRICT_DIRECT_MODE:
404 flag_strict_direct_addressing = 0;
407 case OPTION_GENERATE_EXAMPLE:
408 flag_print_opcodes = 2;
412 if (strcasecmp (arg, "68hc11") == 0)
413 current_architecture = cpu6811;
414 else if (strcasecmp (arg, "68hc12") == 0)
415 current_architecture = cpu6812;
417 as_bad (_("Option `%s' is not recognized."), arg);
428 md_undefined_symbol (name)
429 char *name ATTRIBUTE_UNUSED;
434 /* Equal to MAX_PRECISION in atof-ieee.c. */
435 #define MAX_LITTLENUMS 6
437 /* Turn a string in input_line_pointer into a floating point constant
438 of type TYPE, and store the appropriate bytes in *LITP. The number
439 of LITTLENUMS emitted is stored in *SIZEP. An error message is
440 returned, or NULL on OK. */
442 md_atof (type, litP, sizeP)
448 LITTLENUM_TYPE words[MAX_LITTLENUMS];
449 LITTLENUM_TYPE *wordP;
480 return _("Bad call to MD_ATOF()");
482 t = atof_ieee (input_line_pointer, type, words);
484 input_line_pointer = t;
486 *sizeP = prec * sizeof (LITTLENUM_TYPE);
487 for (wordP = words; prec--;)
489 md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE));
490 litP += sizeof (LITTLENUM_TYPE);
496 md_section_align (seg, addr)
500 int align = bfd_get_section_alignment (stdoutput, seg);
501 return ((addr + (1 << align) - 1) & (-1 << align));
505 cmp_opcode (op1, op2)
506 struct m68hc11_opcode *op1;
507 struct m68hc11_opcode *op2;
509 return strcmp (op1->name, op2->name);
512 /* Initialize the assembler. Create the opcode hash table
513 (sorted on the names) with the M6811 opcode table
514 (from opcode library). */
518 char *prev_name = "";
519 struct m68hc11_opcode *opcodes;
520 struct m68hc11_opcode_def *opc = 0;
523 get_default_target ();
525 m68hc11_hash = hash_new ();
527 /* Get a writable copy of the opcode table and sort it on the names. */
528 opcodes = (struct m68hc11_opcode *) xmalloc (m68hc11_num_opcodes *
531 m68hc11_sorted_opcodes = opcodes;
533 for (i = 0; i < m68hc11_num_opcodes; i++)
535 if (m68hc11_opcodes[i].arch & current_architecture)
537 opcodes[num_opcodes] = m68hc11_opcodes[i];
538 if (opcodes[num_opcodes].name[0] == 'b'
539 && opcodes[num_opcodes].format & M6811_OP_JUMP_REL
540 && !(opcodes[num_opcodes].format & M6811_OP_BITMASK))
543 opcodes[num_opcodes] = m68hc11_opcodes[i];
546 for (j = 0; alias_opcodes[j].name != 0; j++)
547 if (strcmp (m68hc11_opcodes[i].name, alias_opcodes[j].name) == 0)
549 opcodes[num_opcodes] = m68hc11_opcodes[i];
550 opcodes[num_opcodes].name = alias_opcodes[j].alias;
556 qsort (opcodes, num_opcodes, sizeof (struct m68hc11_opcode), cmp_opcode);
558 opc = (struct m68hc11_opcode_def *)
559 xmalloc (num_opcodes * sizeof (struct m68hc11_opcode_def));
560 m68hc11_opcode_defs = opc--;
562 /* Insert unique names into hash table. The M6811 instruction set
563 has several identical opcode names that have different opcodes based
564 on the operands. This hash table then provides a quick index to
565 the first opcode with a particular name in the opcode table. */
566 for (i = 0; i < num_opcodes; i++, opcodes++)
570 if (strcmp (prev_name, opcodes->name))
572 prev_name = (char *) opcodes->name;
576 opc->min_operands = 100;
577 opc->max_operands = 0;
579 opc->opcode = opcodes;
581 hash_insert (m68hc11_hash, opcodes->name, (char *) opc);
584 opc->format |= opcodes->format;
586 /* See how many operands this opcode needs. */
588 if (opcodes->format & M6811_OP_MASK)
590 if (opcodes->format & M6811_OP_BITMASK)
592 if (opcodes->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
594 if (opcodes->format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2))
597 if (expect < opc->min_operands)
598 opc->min_operands = expect;
599 if (expect > opc->max_operands)
600 opc->max_operands = expect;
603 m68hc11_nb_opcode_defs = opc - m68hc11_opcode_defs;
605 if (flag_print_opcodes)
607 print_opcode_list ();
613 m68hc11_init_after_args ()
619 /* Return a string that represents the operand format for the instruction.
620 When example is true, this generates an example of operand. This is used
621 to give an example and also to generate a test. */
623 print_opcode_format (opcode, example)
624 struct m68hc11_opcode *opcode;
627 static char buf[128];
628 int format = opcode->format;
633 if (format & M6811_OP_IMM8)
636 sprintf (p, "#%d", rand () & 0x0FF);
638 strcpy (p, _("#<imm8>"));
642 if (format & M6811_OP_IMM16)
645 sprintf (p, "#%d", rand () & 0x0FFFF);
647 strcpy (p, _("#<imm16>"));
651 if (format & M6811_OP_IX)
654 sprintf (p, "%d,X", rand () & 0x0FF);
656 strcpy (p, _("<imm8>,X"));
660 if (format & M6811_OP_IY)
663 sprintf (p, "%d,X", rand () & 0x0FF);
665 strcpy (p, _("<imm8>,X"));
669 if (format & M6812_OP_IDX)
672 sprintf (p, "%d,X", rand () & 0x0FF);
678 if (format & M6811_OP_DIRECT)
681 sprintf (p, "*Z%d", rand () & 0x0FF);
683 strcpy (p, _("*<abs8>"));
687 if (format & M6811_OP_BITMASK)
693 sprintf (p, "#$%02x", rand () & 0x0FF);
695 strcpy (p, _("#<mask>"));
698 if (format & M6811_OP_JUMP_REL)
702 if (format & M6811_OP_IND16)
705 sprintf (p, _("symbol%d"), rand () & 0x0FF);
707 strcpy (p, _("<abs>"));
712 if (format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
716 if (format & M6811_OP_BITMASK)
718 sprintf (p, ".+%d", rand () & 0x7F);
722 sprintf (p, "L%d", rand () & 0x0FF);
726 strcpy (p, _("<label>"));
732 /* Prints the list of instructions with the possible operands. */
737 char *prev_name = "";
738 struct m68hc11_opcode *opcodes;
739 int example = flag_print_opcodes == 2;
742 printf (_("# Example of `%s' instructions\n\t.sect .text\n_start:\n"),
745 opcodes = m68hc11_sorted_opcodes;
747 /* Walk the list sorted on names (by md_begin). We only report
748 one instruction per line, and we collect the different operand
750 for (i = 0; i < num_opcodes; i++, opcodes++)
752 char *fmt = print_opcode_format (opcodes, example);
756 printf ("L%d:\t", i);
757 printf ("%s %s\n", opcodes->name, fmt);
761 if (strcmp (prev_name, opcodes->name))
766 printf ("%-5.5s ", opcodes->name);
767 prev_name = (char *) opcodes->name;
770 printf (" [%s]", fmt);
776 /* Print the instruction format. This operation is called when some
777 instruction is not correct. Instruction format is printed as an
780 print_insn_format (name)
783 struct m68hc11_opcode_def *opc;
784 struct m68hc11_opcode *opcode;
787 opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash, name);
790 as_bad (_("Instruction `%s' is not recognized."), name);
793 opcode = opc->opcode;
795 as_bad (_("Instruction formats for `%s':"), name);
800 fmt = print_opcode_format (opcode, 0, 0);
801 sprintf (buf, "\t%-5.5s %s", opcode->name, fmt);
806 while (strcmp (opcode->name, name) == 0);
809 /* Analysis of 68HC11 and 68HC12 operands. */
811 /* reg_name_search() finds the register number given its name.
812 Returns the register number or REG_NONE on failure. */
814 reg_name_search (name)
817 if (strcasecmp (name, "x") == 0 || strcasecmp (name, "ix") == 0)
819 if (strcasecmp (name, "y") == 0 || strcasecmp (name, "iy") == 0)
821 if (strcasecmp (name, "a") == 0)
823 if (strcasecmp (name, "b") == 0)
825 if (strcasecmp (name, "d") == 0)
827 if (strcasecmp (name, "sp") == 0)
829 if (strcasecmp (name, "pc") == 0)
831 if (strcasecmp (name, "ccr") == 0)
841 while (*p == ' ' || *p == '\t')
847 /* Check the string at input_line_pointer
848 to see if it is a valid register name. */
852 register_id reg_number;
853 char c, *p = input_line_pointer;
855 if (!is_name_beginner (*p++))
858 while (is_part_of_name (*p++))
865 /* Look to see if it's in the register table. */
866 reg_number = reg_name_search (input_line_pointer);
867 if (reg_number != REG_NONE)
872 input_line_pointer = p;
881 /* Parse a string of operands and return an array of expressions.
883 Operand mode[0] mode[1] exp[0] exp[1]
884 #n M6811_OP_IMM16 - O_*
885 *<exp> M6811_OP_DIRECT - O_*
886 .{+-}<exp> M6811_OP_JUMP_REL - O_*
887 <exp> M6811_OP_IND16 - O_*
888 ,r N,r M6812_OP_IDX M6812_OP_REG O_constant O_register
889 n,-r M6812_PRE_DEC M6812_OP_REG O_constant O_register
890 n,+r M6812_PRE_INC " "
891 n,r- M6812_POST_DEC " "
892 n,r+ M6812_POST_INC " "
893 A,r B,r D,r M6811_OP_REG M6812_OP_REG O_register O_register
894 [D,r] M6811_OP_IDX_2 M6812_OP_REG O_register O_register
895 [n,r] M6811_OP_IDX_1 M6812_OP_REG O_constant O_register */
897 get_operand (oper, which, opmode)
902 char *p = input_line_pointer;
906 oper->exp.X_op = O_absent;
907 oper->reg1 = REG_NONE;
908 oper->reg2 = REG_NONE;
909 mode = M6811_OP_NONE;
913 if (*p == 0 || *p == '\n' || *p == '\r')
915 input_line_pointer = p;
919 if (*p == '*' && (opmode & (M6811_OP_DIRECT | M6811_OP_IND16)))
921 mode = M6811_OP_DIRECT;
926 if (!(opmode & (M6811_OP_IMM8 | M6811_OP_IMM16 | M6811_OP_BITMASK)))
928 as_bad (_("Immediate operand is not allowed for operand %d."),
933 mode = M6811_OP_IMM16;
935 if (strncmp (p, "%hi", 3) == 0)
938 mode |= M6811_OP_HIGH_ADDR;
940 else if (strncmp (p, "%lo", 3) == 0)
943 mode |= M6811_OP_LOW_ADDR;
946 else if (*p == '.' && (p[1] == '+' || p[1] == '-'))
949 mode = M6811_OP_JUMP_REL;
953 if (current_architecture & cpu6811)
954 as_bad (_("Indirect indexed addressing is not valid for 68HC11."));
957 mode = M6812_OP_IDX_2;
960 else if (*p == ',') /* Special handling of ,x and ,y. */
963 input_line_pointer = p;
965 reg = register_name ();
969 oper->exp.X_op = O_constant;
970 oper->exp.X_add_number = 0;
971 oper->mode = M6812_OP_IDX;
974 as_bad (_("Spurious `,' or bad indirect register addressing mode."));
977 input_line_pointer = p;
979 if (mode == M6811_OP_NONE || mode == M6812_OP_IDX_2)
980 reg = register_name ();
986 p = skip_whites (input_line_pointer);
987 if (*p == ']' && mode == M6812_OP_IDX_2)
990 (_("Missing second register or offset for indexed-indirect mode."));
995 oper->mode = mode | M6812_OP_REG;
998 if (mode == M6812_OP_IDX_2)
1000 as_bad (_("Missing second register for indexed-indirect mode."));
1007 input_line_pointer = p;
1008 reg = register_name ();
1009 if (reg != REG_NONE)
1011 p = skip_whites (input_line_pointer);
1012 if (mode == M6812_OP_IDX_2)
1016 as_bad (_("Missing `]' to close indexed-indirect mode."));
1021 input_line_pointer = p;
1029 /* In MRI mode, isolate the operand because we can't distinguish
1030 operands from comments. */
1035 p = skip_whites (p);
1036 while (*p && *p != ' ' && *p != '\t')
1045 /* Parse as an expression. */
1046 expression (&oper->exp);
1055 expression (&oper->exp);
1058 if (oper->exp.X_op == O_illegal)
1060 as_bad (_("Illegal operand."));
1063 else if (oper->exp.X_op == O_absent)
1065 as_bad (_("Missing operand."));
1069 p = input_line_pointer;
1071 if (mode == M6811_OP_NONE || mode == M6811_OP_DIRECT
1072 || mode == M6812_OP_IDX_2)
1074 p = skip_whites (input_line_pointer);
1080 /* 68HC12 pre increment or decrement. */
1081 if (mode == M6811_OP_NONE)
1085 mode = M6812_PRE_DEC;
1087 if (current_architecture & cpu6811)
1088 as_bad (_("Pre-decrement mode is not valid for 68HC11"));
1092 mode = M6812_PRE_INC;
1094 if (current_architecture & cpu6811)
1095 as_bad (_("Pre-increment mode is not valid for 68HC11"));
1097 p = skip_whites (p);
1099 input_line_pointer = p;
1100 reg = register_name ();
1103 if (which == 0 && opmode & M6812_OP_IDX_P2
1104 && reg != REG_X && reg != REG_Y
1105 && reg != REG_PC && reg != REG_SP)
1108 input_line_pointer = p;
1111 if (reg == REG_NONE && mode != M6811_OP_DIRECT
1112 && !(mode == M6811_OP_NONE && opmode & M6811_OP_IND16))
1114 as_bad (_("Wrong register in register indirect mode."));
1117 if (mode == M6812_OP_IDX_2)
1119 p = skip_whites (input_line_pointer);
1122 as_bad (_("Missing `]' to close register indirect operand."));
1125 input_line_pointer = p;
1127 if (reg != REG_NONE)
1130 if (mode == M6811_OP_NONE)
1132 p = input_line_pointer;
1135 mode = M6812_POST_DEC;
1137 if (current_architecture & cpu6811)
1139 (_("Post-decrement mode is not valid for 68HC11."));
1143 mode = M6812_POST_INC;
1145 if (current_architecture & cpu6811)
1147 (_("Post-increment mode is not valid for 68HC11."));
1150 mode = M6812_OP_IDX;
1152 input_line_pointer = p;
1155 mode |= M6812_OP_IDX;
1162 if (mode == M6812_OP_D_IDX_2)
1164 as_bad (_("Invalid indexed indirect mode."));
1169 /* If the mode is not known until now, this is either a label
1170 or an indirect address. */
1171 if (mode == M6811_OP_NONE)
1172 mode = M6811_OP_IND16 | M6811_OP_JUMP_REL;
1174 p = input_line_pointer;
1175 while (*p == ' ' || *p == '\t')
1177 input_line_pointer = p;
1183 #define M6812_AUTO_INC_DEC (M6812_PRE_INC | M6812_PRE_DEC \
1184 | M6812_POST_INC | M6812_POST_DEC)
1186 /* Checks that the number 'num' fits for a given mode. */
1188 check_range (num, mode)
1192 /* Auto increment and decrement are ok for [-8..8] without 0. */
1193 if (mode & M6812_AUTO_INC_DEC)
1194 return (num != 0 && num <= 8 && num >= -8);
1196 /* The 68HC12 supports 5, 9 and 16-bits offsets. */
1197 if (mode & (M6812_INDEXED_IND | M6812_INDEXED | M6812_OP_IDX))
1198 mode = M6811_OP_IND16;
1200 if (mode & M6812_OP_JUMP_REL16)
1201 mode = M6811_OP_IND16;
1207 case M6811_OP_DIRECT:
1208 return (num >= 0 && num <= 255) ? 1 : 0;
1210 case M6811_OP_BITMASK:
1212 return (((num & 0xFFFFFF00) == 0) || ((num & 0xFFFFFF00) == 0xFFFFFF00))
1215 case M6811_OP_JUMP_REL:
1216 return (num >= -128 && num <= 127) ? 1 : 0;
1218 case M6811_OP_IND16:
1219 case M6811_OP_IMM16:
1220 return (((num & 0xFFFF0000) == 0) || ((num & 0xFFFF0000) == 0xFFFF0000))
1223 case M6812_OP_IBCC_MARKER:
1224 case M6812_OP_TBCC_MARKER:
1225 case M6812_OP_DBCC_MARKER:
1226 return (num >= -256 && num <= 255) ? 1 : 0;
1228 case M6812_OP_TRAP_ID:
1229 return ((num >= 0x30 && num <= 0x39)
1230 || (num >= 0x40 && num <= 0x0ff)) ? 1 : 0;
1237 /* Gas fixup generation. */
1239 /* Put a 1 byte expression described by 'oper'. If this expression contains
1240 unresolved symbols, generate an 8-bit fixup. */
1242 fixup8 (oper, mode, opmode)
1251 if (oper->X_op == O_constant)
1253 if (mode & M6812_OP_TRAP_ID
1254 && !check_range (oper->X_add_number, M6812_OP_TRAP_ID))
1256 static char trap_id_warn_once = 0;
1258 as_bad (_("Trap id `%ld' is out of range."), oper->X_add_number);
1259 if (trap_id_warn_once == 0)
1261 trap_id_warn_once = 1;
1262 as_bad (_("Trap id must be within [0x30..0x39] or [0x40..0xff]."));
1266 if (!(mode & M6812_OP_TRAP_ID)
1267 && !check_range (oper->X_add_number, mode))
1269 as_bad (_("Operand out of 8-bit range: `%ld'."), oper->X_add_number);
1271 number_to_chars_bigendian (f, oper->X_add_number & 0x0FF, 1);
1273 else if (oper->X_op != O_register)
1275 if (mode & M6812_OP_TRAP_ID)
1276 as_bad (_("The trap id must be a constant."));
1278 if (mode == M6811_OP_JUMP_REL)
1282 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
1283 oper, true, BFD_RELOC_8_PCREL);
1284 fixp->fx_pcrel_adjust = 1;
1288 /* Now create an 8-bit fixup. If there was some %hi or %lo
1289 modifier, generate the reloc accordingly. */
1290 fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
1292 ((opmode & M6811_OP_HIGH_ADDR)
1293 ? BFD_RELOC_M68HC11_HI8
1294 : ((opmode & M6811_OP_LOW_ADDR)
1295 ? BFD_RELOC_M68HC11_LO8 : BFD_RELOC_8)));
1297 number_to_chars_bigendian (f, 0, 1);
1301 as_fatal (_("Operand `%x' not recognized in fixup8."), oper->X_op);
1305 /* Put a 2 bytes expression described by 'oper'. If this expression contains
1306 unresolved symbols, generate a 16-bit fixup. */
1308 fixup16 (oper, mode, opmode)
1311 int opmode ATTRIBUTE_UNUSED;
1317 if (oper->X_op == O_constant)
1319 if (!check_range (oper->X_add_number, mode))
1321 as_bad (_("Operand out of 16-bit range: `%ld'."),
1322 oper->X_add_number);
1324 number_to_chars_bigendian (f, oper->X_add_number & 0x0FFFF, 2);
1326 else if (oper->X_op != O_register)
1330 /* Now create a 16-bit fixup. */
1331 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 2,
1333 (mode & M6812_OP_JUMP_REL16 ? true : false),
1334 (mode & M6812_OP_JUMP_REL16
1335 ? BFD_RELOC_16_PCREL : BFD_RELOC_16));
1336 number_to_chars_bigendian (f, 0, 2);
1337 if (mode & M6812_OP_JUMP_REL16)
1338 fixp->fx_pcrel_adjust = 2;
1342 as_fatal (_("Operand `%x' not recognized in fixup16."), oper->X_op);
1346 /* 68HC11 and 68HC12 code generation. */
1348 /* Translate the short branch/bsr instruction into a long branch. */
1349 static unsigned char
1350 convert_branch (code)
1353 if (IS_OPCODE (code, M6812_BSR))
1355 else if (IS_OPCODE (code, M6811_BSR))
1357 else if (IS_OPCODE (code, M6811_BRA))
1358 return (current_architecture & cpu6812) ? M6812_JMP : M6811_JMP;
1360 as_fatal (_("Unexpected branch conversion with `%x'"), code);
1362 /* Keep gcc happy. */
1366 /* Start a new insn that contains at least 'size' bytes. Record the
1367 line information of that insn in the dwarf2 debug sections. */
1369 m68hc11_new_insn (size)
1374 f = frag_more (size);
1376 /* Emit line number information in dwarf2 debug sections. */
1377 if (debug_type == DEBUG_DWARF2)
1381 dwarf2_where (&debug_line);
1382 addr = frag_now->fr_address + frag_now_fix () - size;
1383 dwarf2_gen_line_info (addr, &debug_line);
1388 /* Builds a jump instruction (bra, bcc, bsr). */
1390 build_jump_insn (opcode, operands, nb_operands, jmp_mode)
1391 struct m68hc11_opcode *opcode;
1401 /* The relative branch convertion is not supported for
1403 assert ((opcode->format & M6811_OP_BITMASK) == 0);
1404 assert (nb_operands == 1);
1405 assert (operands[0].reg1 == REG_NONE && operands[0].reg2 == REG_NONE);
1407 code = opcode->opcode;
1410 n = operands[0].exp.X_add_number;
1412 /* Turn into a long branch:
1413 - when force long branch option (and not for jbcc pseudos),
1414 - when jbcc and the constant is out of -128..127 range,
1415 - when branch optimization is allowed and branch out of range. */
1416 if ((jmp_mode == 0 && flag_force_long_jumps)
1417 || (operands[0].exp.X_op == O_constant
1418 && (!check_range (n, opcode->format) &&
1419 (jmp_mode == 1 || flag_fixed_branchs == 0))))
1421 if (code == M6811_BSR || code == M6811_BRA || code == M6812_BSR)
1423 code = convert_branch (code);
1425 f = m68hc11_new_insn (1);
1426 number_to_chars_bigendian (f, code, 1);
1428 else if (current_architecture & cpu6812)
1430 /* 68HC12: translate the bcc into a lbcc. */
1431 f = m68hc11_new_insn (2);
1432 number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1);
1433 number_to_chars_bigendian (f + 1, code, 1);
1434 fixup16 (&operands[0].exp, M6812_OP_JUMP_REL16,
1435 M6812_OP_JUMP_REL16);
1440 /* 68HC11: translate the bcc into b!cc +3; jmp <L>. */
1441 f = m68hc11_new_insn (3);
1443 number_to_chars_bigendian (f, code, 1);
1444 number_to_chars_bigendian (f + 1, 3, 1);
1445 number_to_chars_bigendian (f + 2, M6811_JMP, 1);
1447 fixup16 (&operands[0].exp, M6811_OP_IND16, M6811_OP_IND16);
1451 /* Branch with a constant that must fit in 8-bits. */
1452 if (operands[0].exp.X_op == O_constant)
1454 if (!check_range (n, opcode->format))
1456 as_bad (_("Operand out of range for a relative branch: `%ld'"),
1459 else if (opcode->format & M6812_OP_JUMP_REL16)
1461 f = m68hc11_new_insn (4);
1462 number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1);
1463 number_to_chars_bigendian (f + 1, code, 1);
1464 number_to_chars_bigendian (f + 2, n & 0x0ffff, 2);
1468 f = m68hc11_new_insn (2);
1469 number_to_chars_bigendian (f, code, 1);
1470 number_to_chars_bigendian (f + 1, n & 0x0FF, 1);
1473 else if (opcode->format & M6812_OP_JUMP_REL16)
1475 f = m68hc11_new_insn (2);
1476 number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1);
1477 number_to_chars_bigendian (f + 1, code, 1);
1478 fixup16 (&operands[0].exp, M6812_OP_JUMP_REL16, M6812_OP_JUMP_REL16);
1484 /* Branch offset must fit in 8-bits, don't do some relax. */
1485 if (jmp_mode == 0 && flag_fixed_branchs)
1487 opcode = m68hc11_new_insn (1);
1488 number_to_chars_bigendian (opcode, code, 1);
1489 fixup8 (&operands[0].exp, M6811_OP_JUMP_REL, M6811_OP_JUMP_REL);
1492 /* bra/bsr made be changed into jmp/jsr. */
1493 else if (code == M6811_BSR || code == M6811_BRA || code == M6812_BSR)
1495 opcode = m68hc11_new_insn (2);
1496 number_to_chars_bigendian (opcode, code, 1);
1497 number_to_chars_bigendian (opcode + 1, 0, 1);
1498 frag_var (rs_machine_dependent, 1, 1,
1499 ENCODE_RELAX (STATE_PC_RELATIVE, STATE_UNDF),
1500 operands[0].exp.X_add_symbol, (offsetT) n, opcode);
1502 else if (current_architecture & cpu6812)
1504 opcode = m68hc11_new_insn (2);
1505 number_to_chars_bigendian (opcode, code, 1);
1506 number_to_chars_bigendian (opcode + 1, 0, 1);
1507 frag_var (rs_machine_dependent, 2, 2,
1508 ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_UNDF),
1509 operands[0].exp.X_add_symbol, (offsetT) n, opcode);
1513 opcode = m68hc11_new_insn (2);
1514 number_to_chars_bigendian (opcode, code, 1);
1515 number_to_chars_bigendian (opcode + 1, 0, 1);
1516 frag_var (rs_machine_dependent, 3, 3,
1517 ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_UNDF),
1518 operands[0].exp.X_add_symbol, (offsetT) n, opcode);
1523 /* Builds a dbne/dbeq/tbne/tbeq instruction. */
1525 build_dbranch_insn (opcode, operands, nb_operands, jmp_mode)
1526 struct m68hc11_opcode *opcode;
1536 /* The relative branch convertion is not supported for
1538 assert ((opcode->format & M6811_OP_BITMASK) == 0);
1539 assert (nb_operands == 2);
1540 assert (operands[0].reg1 != REG_NONE);
1542 code = opcode->opcode & 0x0FF;
1545 f = m68hc11_new_insn (1);
1546 number_to_chars_bigendian (f, code, 1);
1548 n = operands[1].exp.X_add_number;
1549 code = operands[0].reg1;
1551 if (operands[0].reg1 == REG_NONE || operands[0].reg1 == REG_CCR
1552 || operands[0].reg1 == REG_PC)
1553 as_bad (_("Invalid register for dbcc/tbcc instruction."));
1555 if (opcode->format & M6812_OP_IBCC_MARKER)
1557 else if (opcode->format & M6812_OP_TBCC_MARKER)
1560 if (!(opcode->format & M6812_OP_EQ_MARKER))
1563 /* Turn into a long branch:
1564 - when force long branch option (and not for jbcc pseudos),
1565 - when jdbcc and the constant is out of -256..255 range,
1566 - when branch optimization is allowed and branch out of range. */
1567 if ((jmp_mode == 0 && flag_force_long_jumps)
1568 || (operands[1].exp.X_op == O_constant
1569 && (!check_range (n, M6812_OP_IBCC_MARKER) &&
1570 (jmp_mode == 1 || flag_fixed_branchs == 0))))
1574 number_to_chars_bigendian (f, code, 1);
1575 number_to_chars_bigendian (f + 1, M6812_JMP, 1);
1576 fixup16 (&operands[0].exp, M6811_OP_IND16, M6811_OP_IND16);
1580 /* Branch with a constant that must fit in 9-bits. */
1581 if (operands[1].exp.X_op == O_constant)
1583 if (!check_range (n, M6812_OP_IBCC_MARKER))
1585 as_bad (_("Operand out of range for a relative branch: `%ld'"),
1594 number_to_chars_bigendian (f, code, 1);
1595 number_to_chars_bigendian (f + 1, n & 0x0FF, 1);
1600 /* Branch offset must fit in 8-bits, don't do some relax. */
1601 if (jmp_mode == 0 && flag_fixed_branchs)
1603 fixup8 (&operands[0].exp, M6811_OP_JUMP_REL, M6811_OP_JUMP_REL);
1609 number_to_chars_bigendian (f, code, 1);
1610 number_to_chars_bigendian (f + 1, 0, 1);
1611 frag_var (rs_machine_dependent, 3, 3,
1612 ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_UNDF),
1613 operands[1].exp.X_add_symbol, (offsetT) n, f);
1618 #define OP_EXTENDED (M6811_OP_PAGE2 | M6811_OP_PAGE3 | M6811_OP_PAGE4)
1620 /* Assemble the post index byte for 68HC12 extended addressing modes. */
1622 build_indexed_byte (op, format, move_insn)
1624 int format ATTRIBUTE_UNUSED;
1627 unsigned char byte = 0;
1632 val = op->exp.X_add_number;
1634 if (mode & M6812_AUTO_INC_DEC)
1637 if (mode & (M6812_POST_INC | M6812_POST_DEC))
1640 if (op->exp.X_op == O_constant)
1642 if (!check_range (val, mode))
1644 as_bad (_("Increment/decrement value is out of range: `%ld'."),
1647 if (mode & (M6812_POST_INC | M6812_PRE_INC))
1648 byte |= (val - 1) & 0x07;
1650 byte |= (8 - ((val) & 7)) | 0x8;
1655 as_fatal (_("Expecting a register."));
1670 as_bad (_("Invalid register for post/pre increment."));
1675 number_to_chars_bigendian (f, byte, 1);
1679 if (mode & M6812_OP_IDX)
1700 as_bad (_("Invalid register."));
1703 if (op->exp.X_op == O_constant)
1705 if (!check_range (val, M6812_OP_IDX))
1707 as_bad (_("Offset out of 16-bit range: %ld."), val);
1710 if (move_insn && !(val >= -16 && val <= 15))
1712 as_bad (_("Offset out of 5-bit range for movw/movb insn."));
1716 if (val >= -16 && val <= 15 && !(mode & M6812_OP_IDX_2))
1721 number_to_chars_bigendian (f, byte, 1);
1724 else if (val >= -256 && val <= 255 && !(mode & M6812_OP_IDX_2))
1731 number_to_chars_bigendian (f, byte, 1);
1732 number_to_chars_bigendian (f + 1, val & 0x0FF, 1);
1738 if (mode & M6812_OP_IDX_2)
1744 number_to_chars_bigendian (f, byte, 1);
1745 number_to_chars_bigendian (f + 1, val & 0x0FFFF, 2);
1750 number_to_chars_bigendian (f, byte, 1);
1752 fix_new_exp (frag_now, f - frag_now->fr_literal, 2,
1753 &op->exp, false, BFD_RELOC_16);
1755 frag_var (rs_machine_dependent, 2, 2,
1756 ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_UNDF),
1757 op->exp.X_add_symbol, val, f);
1761 if (mode & M6812_OP_REG)
1763 if (mode & M6812_OP_IDX_2)
1765 if (op->reg1 != REG_D)
1766 as_bad (_("Expecting register D for indexed indirect mode."));
1768 as_bad (_("Indexed indirect mode is not allowed for movb/movw."));
1785 as_bad (_("Invalid accumulator register."));
1810 as_bad (_("Invalid indexed register."));
1814 number_to_chars_bigendian (f, byte, 1);
1818 as_fatal (_("Addressing mode not implemented yet."));
1822 /* Assemble the 68HC12 register mode byte. */
1824 build_reg_mode (op, format)
1831 if (format & M6812_OP_SEX_MARKER
1832 && op->reg1 != REG_A && op->reg1 != REG_B && op->reg1 != REG_CCR)
1833 as_bad (_("Invalid source register for this instruction, use 'tfr'."));
1834 else if (op->reg1 == REG_NONE || op->reg1 == REG_PC)
1835 as_bad (_("Invalid source register."));
1837 if (format & M6812_OP_SEX_MARKER
1838 && op->reg2 != REG_D
1839 && op->reg2 != REG_X && op->reg2 != REG_Y && op->reg2 != REG_SP)
1840 as_bad (_("Invalid destination register for this instruction, use 'tfr'."));
1841 else if (op->reg2 == REG_NONE || op->reg2 == REG_PC)
1842 as_bad (_("Invalid destination register."));
1844 byte = (op->reg1 << 4) | (op->reg2);
1845 if (format & M6812_OP_EXG_MARKER)
1849 number_to_chars_bigendian (f, byte, 1);
1853 /* build_insn takes a pointer to the opcode entry in the opcode table,
1854 the array of operand expressions and builds the correspding instruction.
1855 This operation only deals with non relative jumps insn (need special
1858 build_insn (opcode, operands, nb_operands)
1859 struct m68hc11_opcode *opcode;
1861 int nb_operands ATTRIBUTE_UNUSED;
1869 /* Put the page code instruction if there is one. */
1870 format = opcode->format;
1871 if (format & OP_EXTENDED)
1875 f = m68hc11_new_insn (2);
1876 if (format & M6811_OP_PAGE2)
1877 page_code = M6811_OPCODE_PAGE2;
1878 else if (format & M6811_OP_PAGE3)
1879 page_code = M6811_OPCODE_PAGE3;
1881 page_code = M6811_OPCODE_PAGE4;
1883 number_to_chars_bigendian (f, page_code, 1);
1888 f = m68hc11_new_insn (1);
1890 number_to_chars_bigendian (f, opcode->opcode, 1);
1894 /* The 68HC12 movb and movw instructions are special. We have to handle
1895 them in a special way. */
1896 if (format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2))
1899 if (format & M6812_OP_IDX)
1901 insn_size += build_indexed_byte (&operands[0], format, 1);
1903 format &= ~M6812_OP_IDX;
1905 if (format & M6812_OP_IDX_P2)
1907 insn_size += build_indexed_byte (&operands[1], format, 1);
1909 format &= ~M6812_OP_IDX_P2;
1913 if (format & (M6811_OP_DIRECT | M6811_OP_IMM8))
1916 fixup8 (&operands[i].exp,
1917 format & (M6811_OP_DIRECT | M6811_OP_IMM8 | M6812_OP_TRAP_ID),
1921 else if (format & (M6811_OP_IMM16 | M6811_OP_IND16))
1924 fixup16 (&operands[i].exp, format & (M6811_OP_IMM16 | M6811_OP_IND16),
1928 else if (format & (M6811_OP_IX | M6811_OP_IY))
1930 if ((format & M6811_OP_IX) && (operands[0].reg1 != REG_X))
1931 as_bad (_("Invalid indexed register, expecting register X."));
1932 if ((format & M6811_OP_IY) && (operands[0].reg1 != REG_Y))
1933 as_bad (_("Invalid indexed register, expecting register Y."));
1936 fixup8 (&operands[0].exp, M6811_OP_IX, operands[0].mode);
1940 (M6812_OP_IDX | M6812_OP_IDX_2 | M6812_OP_IDX_1 | M6812_OP_D_IDX))
1942 insn_size += build_indexed_byte (&operands[i], format, move_insn);
1945 else if (format & M6812_OP_REG && current_architecture & cpu6812)
1947 insn_size += build_reg_mode (&operands[i], format);
1950 if (format & M6811_OP_BITMASK)
1953 fixup8 (&operands[i].exp, M6811_OP_BITMASK, operands[i].mode);
1956 if (format & M6811_OP_JUMP_REL)
1959 fixup8 (&operands[i].exp, M6811_OP_JUMP_REL, operands[i].mode);
1962 else if (format & M6812_OP_IND16_P2)
1965 fixup16 (&operands[1].exp, M6811_OP_IND16, operands[1].mode);
1969 /* Opcode identification and operand analysis. */
1971 /* find() gets a pointer to an entry in the opcode table. It must look at all
1972 opcodes with the same name and use the operands to choose the correct
1973 opcode. Returns the opcode pointer if there was a match and 0 if none. */
1974 static struct m68hc11_opcode *
1975 find (opc, operands, nb_operands)
1976 struct m68hc11_opcode_def *opc;
1981 struct m68hc11_opcode *opcode;
1982 struct m68hc11_opcode *op_indirect;
1985 opcode = opc->opcode;
1987 /* Now search the opcode table table for one with operands
1988 that matches what we've got. We're only done if the operands matched so
1989 far AND there are no more to check. */
1990 for (pos = match = 0; match == 0 && pos < opc->nb_modes; pos++, opcode++)
1992 int poss_indirect = 0;
1993 long format = opcode->format;
1997 if (opcode->format & M6811_OP_MASK)
1999 if (opcode->format & M6811_OP_BITMASK)
2001 if (opcode->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
2003 if (opcode->format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2))
2006 for (i = 0; expect == nb_operands && i < nb_operands; i++)
2008 int mode = operands[i].mode;
2010 if (mode & M6811_OP_IMM16)
2013 (M6811_OP_IMM8 | M6811_OP_IMM16 | M6811_OP_BITMASK))
2017 if (mode == M6811_OP_DIRECT)
2019 if (format & M6811_OP_DIRECT)
2022 /* If the operand is a page 0 operand, remember a
2023 possible <abs-16> addressing mode. We mark
2024 this and continue to check other operands. */
2025 if (format & M6811_OP_IND16
2026 && flag_strict_direct_addressing && op_indirect == 0)
2033 if (mode & M6811_OP_IND16)
2035 if (i == 0 && (format & M6811_OP_IND16) != 0)
2037 if (i != 0 && (format & M6812_OP_IND16_P2) != 0)
2039 if (i == 0 && (format & M6811_OP_BITMASK))
2042 if (mode & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
2044 if (format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
2047 if (mode & M6812_OP_REG)
2049 if (i == 0 && format & M6812_OP_REG
2050 && operands[i].reg2 == REG_NONE)
2052 if (i == 0 && format & M6812_OP_REG
2053 && format & M6812_OP_REG_2 && operands[i].reg2 != REG_NONE)
2057 if (i == 0 && format & M6812_OP_D_IDX)
2059 if (i == 0 && (format & M6812_OP_IDX)
2060 && (format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2)))
2062 if (i == 1 && format & M6812_OP_IDX_P2)
2066 if (mode & M6812_OP_IDX)
2068 if (format & M6811_OP_IX && operands[i].reg1 == REG_X)
2070 if (format & M6811_OP_IY && operands[i].reg1 == REG_Y)
2073 && format & (M6812_OP_IDX | M6812_OP_IDX_1 | M6812_OP_IDX_2)
2074 && (operands[i].reg1 == REG_X
2075 || operands[i].reg1 == REG_Y
2076 || operands[i].reg1 == REG_SP
2077 || operands[i].reg1 == REG_PC))
2079 if (i == 1 && format & M6812_OP_IDX_P2)
2082 if (mode & M6812_AUTO_INC_DEC)
2085 && format & (M6812_OP_IDX | M6812_OP_IDX_1 |
2088 if (i == 1 && format & M6812_OP_IDX_P2)
2093 match = i == nb_operands;
2095 /* Operands are ok but an operand uses page 0 addressing mode
2096 while the insn supports abs-16 mode. Keep a reference to this
2097 insns in case there is no insn supporting page 0 addressing. */
2098 if (match && poss_indirect)
2100 op_indirect = opcode;
2107 /* Page 0 addressing is used but not supported by any insn.
2108 If absolute addresses are supported, we use that insn. */
2109 if (match == 0 && op_indirect)
2111 opcode = op_indirect;
2123 /* Find the real opcode and its associated operands. We use a progressive
2124 approach here. On entry, 'opc' points to the first opcode in the
2125 table that matches the opcode name in the source line. We try to
2126 isolate an operand, find a possible match in the opcode table.
2127 We isolate another operand if no match were found. The table 'operands'
2128 is filled while operands are recognized.
2130 Returns the opcode pointer that matches the opcode name in the
2131 source line and the associated operands. */
2132 static struct m68hc11_opcode *
2133 find_opcode (opc, operands, nb_operands)
2134 struct m68hc11_opcode_def *opc;
2138 struct m68hc11_opcode *opcode;
2141 if (opc->max_operands == 0)
2147 for (i = 0; i < opc->max_operands;)
2151 result = get_operand (&operands[i], i, opc->format);
2155 /* Special case where the bitmask of the bclr/brclr
2156 instructions is not introduced by #.
2157 Example: bclr 3,x $80. */
2158 if (i == 1 && (opc->format & M6811_OP_BITMASK)
2159 && (operands[i].mode & M6811_OP_IND16))
2161 operands[i].mode = M6811_OP_IMM16;
2166 if (i >= opc->min_operands)
2168 opcode = find (opc, operands, i);
2173 if (*input_line_pointer == ',')
2174 input_line_pointer++;
2180 #define M6812_XBCC_MARKER (M6812_OP_TBCC_MARKER \
2181 | M6812_OP_DBCC_MARKER \
2182 | M6812_OP_IBCC_MARKER)
2184 /* Gas line assembler entry point. */
2186 /* This is the main entry point for the machine-dependent assembler. str
2187 points to a machine-dependent instruction. This function is supposed to
2188 emit the frags/bytes it assembles to. */
2193 struct m68hc11_opcode_def *opc;
2194 struct m68hc11_opcode *opcode;
2196 unsigned char *op_start, *save;
2197 unsigned char *op_end;
2200 operand operands[M6811_MAX_OPERANDS];
2202 int branch_optimize = 0;
2205 /* Drop leading whitespace. */
2209 /* Find the opcode end and get the opcode in 'name'. The opcode is forced
2210 lower case (the opcode table only has lower case op-codes). */
2211 for (op_start = op_end = (unsigned char *) (str);
2212 *op_end && nlen < 20 && !is_end_of_line[*op_end] && *op_end != ' ';
2215 name[nlen] = tolower (op_start[nlen]);
2222 as_bad (_("No instruction or missing opcode."));
2226 /* Find the opcode definition given its name. */
2227 opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash, name);
2229 /* If it's not recognized, look for 'jbsr' and 'jbxx'. These are
2230 pseudo insns for relative branch. For these branchs, we always
2231 optimize them (turned into absolute branchs) even if --short-branchs
2233 if (opc == NULL && name[0] == 'j' && name[1] == 'b')
2235 opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash, &name[1]);
2237 && (!(opc->format & M6811_OP_JUMP_REL)
2238 || (opc->format & M6811_OP_BITMASK)))
2241 branch_optimize = 1;
2244 /* The following test should probably be removed. This is not conform
2245 to Motorola assembler specs. */
2246 if (opc == NULL && flag_mri)
2248 if (*op_end == ' ' || *op_end == '\t')
2250 while (*op_end == ' ' || *op_end == '\t')
2255 (is_end_of_line[op_end[1]]
2256 || op_end[1] == ' ' || op_end[1] == '\t'
2257 || !isalnum (op_end[1])))
2258 && (*op_end == 'a' || *op_end == 'b'
2259 || *op_end == 'A' || *op_end == 'B'
2260 || *op_end == 'd' || *op_end == 'D'
2261 || *op_end == 'x' || *op_end == 'X'
2262 || *op_end == 'y' || *op_end == 'Y'))
2264 name[nlen++] = tolower (*op_end++);
2266 opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash,
2272 /* Identify a possible instruction alias. There are some on the
2273 68HC12 to emulate a fiew 68HC11 instructions. */
2274 if (opc == NULL && (current_architecture & cpu6812))
2278 for (i = 0; i < m68hc12_num_alias; i++)
2279 if (strcmp (m68hc12_alias[i].name, name) == 0)
2285 if (opc == NULL && alias_id < 0)
2287 as_bad (_("Opcode `%s' is not recognized."), name);
2290 save = input_line_pointer;
2291 input_line_pointer = op_end;
2296 opcode = find_opcode (opc, operands, &nb_operands);
2301 if ((opcode || alias_id >= 0) && !flag_mri)
2303 char *p = input_line_pointer;
2305 while (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r')
2308 if (*p != '\n' && *p)
2309 as_bad (_("Garbage at end of instruction: `%s'."), p);
2312 input_line_pointer = save;
2316 char *f = m68hc11_new_insn (m68hc12_alias[alias_id].size);
2318 number_to_chars_bigendian (f, m68hc12_alias[alias_id].code1, 1);
2319 if (m68hc12_alias[alias_id].size > 1)
2320 number_to_chars_bigendian (f + 1, m68hc12_alias[alias_id].code2, 1);
2325 /* Opcode is known but does not have valid operands. Print out the
2326 syntax for this opcode. */
2329 if (flag_print_insn_syntax)
2330 print_insn_format (name);
2332 as_bad (_("Invalid operand for `%s'"), name);
2336 /* Treat dbeq/ibeq/tbeq instructions in a special way. The branch is
2337 relative and must be in the range -256..255 (9-bits). */
2338 if ((opcode->format & M6812_XBCC_MARKER)
2339 && (opcode->format & M6811_OP_JUMP_REL))
2340 build_dbranch_insn (opcode, operands, nb_operands);
2342 /* Relative jumps instructions are taken care of separately. We have to make
2343 sure that the relative branch is within the range -128..127. If it's out
2344 of range, the instructions are changed into absolute instructions.
2345 This is not supported for the brset and brclr instructions. */
2346 else if ((opcode->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
2347 && !(opcode->format & M6811_OP_BITMASK))
2348 build_jump_insn (opcode, operands, nb_operands, branch_optimize);
2350 build_insn (opcode, operands, nb_operands);
2353 /* Relocation, relaxation and frag conversions. */
2355 md_pcrel_from_section (fixp, sec)
2360 if (fixp->fx_addsy != (symbolS *) NULL
2361 && (!S_IS_DEFINED (fixp->fx_addsy)
2362 || (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
2365 adjust = fixp->fx_pcrel_adjust;
2366 return fixp->fx_frag->fr_address + fixp->fx_where + adjust;
2369 /* If while processing a fixup, a reloc really needs to be created
2370 then it is done here. */
2372 tc_gen_reloc (section, fixp)
2378 reloc = (arelent *) xmalloc (sizeof (arelent));
2379 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
2380 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
2381 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
2382 if (fixp->fx_r_type == 0)
2383 reloc->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_16);
2385 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
2386 if (reloc->howto == (reloc_howto_type *) NULL)
2388 as_bad_where (fixp->fx_file, fixp->fx_line,
2389 _("Relocation %d is not supported by object file format."),
2390 (int) fixp->fx_r_type);
2394 if (!fixp->fx_pcrel)
2395 reloc->addend = fixp->fx_addnumber;
2397 reloc->addend = (section->vma
2398 + (fixp->fx_pcrel_adjust == 64
2399 ? -1 : fixp->fx_pcrel_adjust)
2400 + fixp->fx_addnumber
2401 + md_pcrel_from_section (fixp, section));
2406 md_convert_frag (abfd, sec, fragP)
2407 bfd *abfd ATTRIBUTE_UNUSED;
2408 asection *sec ATTRIBUTE_UNUSED;
2413 char *buffer_address = fragP->fr_literal;
2415 /* Address in object code of the displacement. */
2416 register int object_address = fragP->fr_fix + fragP->fr_address;
2418 buffer_address += fragP->fr_fix;
2420 /* The displacement of the address, from current location. */
2421 disp = fragP->fr_symbol ? S_GET_VALUE (fragP->fr_symbol) : 0;
2422 disp = (disp + fragP->fr_offset) - object_address;
2423 disp += symbol_get_frag (fragP->fr_symbol)->fr_address;
2425 switch (fragP->fr_subtype)
2427 case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE):
2428 fragP->fr_opcode[1] = disp;
2431 case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD):
2432 /* This relax is only for bsr and bra. */
2433 assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
2434 || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
2435 || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
2437 fragP->fr_opcode[0] = convert_branch (fragP->fr_opcode[0]);
2439 fix_new (fragP, fragP->fr_fix - 1, 2,
2440 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
2444 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_BYTE):
2445 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_BYTE):
2446 fragP->fr_opcode[1] = disp;
2449 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_WORD):
2450 /* Invert branch. */
2451 fragP->fr_opcode[0] ^= 1;
2452 fragP->fr_opcode[1] = 3; /* Branch offset. */
2453 buffer_address[0] = M6811_JMP;
2454 fix_new (fragP, fragP->fr_fix + 1, 2,
2455 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
2459 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_WORD):
2460 /* Translate branch into a long branch. */
2461 fragP->fr_opcode[1] = fragP->fr_opcode[0];
2462 fragP->fr_opcode[0] = M6811_OPCODE_PAGE2;
2464 fixp = fix_new (fragP, fragP->fr_fix, 2,
2465 fragP->fr_symbol, fragP->fr_offset, 1,
2466 BFD_RELOC_16_PCREL);
2467 fixp->fx_pcrel_adjust = 2;
2471 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS5):
2472 fragP->fr_opcode[0] = fragP->fr_opcode[0] << 5;
2473 fragP->fr_opcode[0] |= disp & 0x1f;
2476 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9):
2477 fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3);
2478 fragP->fr_opcode[0] |= 0xE0;
2479 fix_new (fragP, fragP->fr_fix + 1, 1,
2480 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_8);
2484 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16):
2485 fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3);
2486 fragP->fr_opcode[0] |= 0xE2;
2487 fix_new (fragP, fragP->fr_fix, 2,
2488 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
2492 case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_BYTE):
2494 fragP->fr_opcode[0] |= 0x10;
2496 fragP->fr_opcode[1] = disp & 0x0FF;
2499 case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_WORD):
2500 /* Invert branch. */
2501 fragP->fr_opcode[0] ^= 0x20;
2502 fragP->fr_opcode[1] = 3; /* Branch offset. */
2503 buffer_address[0] = M6812_JMP;
2504 fix_new (fragP, fragP->fr_fix + 1, 2,
2505 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
2514 /* Force truly undefined symbols to their maximum size, and generally set up
2515 the frag list to be relaxed. */
2517 md_estimate_size_before_relax (fragP, segment)
2522 char *buffer_address = fragP->fr_fix + fragP->fr_literal;
2524 old_fr_fix = fragP->fr_fix;
2526 switch (fragP->fr_subtype)
2528 case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_UNDF):
2530 /* This relax is only for bsr and bra. */
2531 assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
2532 || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
2533 || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
2535 /* A relaxable case. */
2536 if (S_GET_SEGMENT (fragP->fr_symbol) == segment)
2538 fragP->fr_subtype = ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE);
2542 if (flag_fixed_branchs)
2543 as_bad_where (fragP->fr_file, fragP->fr_line,
2544 _("bra or bsr with undefined symbol."));
2546 /* The symbol is undefined or in a separate section. Turn bra into a
2547 jmp and bsr into a jsr. The insn becomes 3 bytes long (instead of
2548 2). A fixup is necessary for the unresolved symbol address. */
2550 fragP->fr_opcode[0] = convert_branch (fragP->fr_opcode[0]);
2553 fix_new (fragP, old_fr_fix - 1, 2, fragP->fr_symbol,
2554 fragP->fr_offset, 0, BFD_RELOC_16);
2559 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_UNDF):
2560 assert (current_architecture & cpu6811);
2562 if (S_GET_SEGMENT (fragP->fr_symbol) == segment)
2564 fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH,
2569 fragP->fr_opcode[0] ^= 1; /* Reverse sense of branch. */
2570 fragP->fr_opcode[1] = 3; /* Skip next jmp insn (3 bytes). */
2572 /* Don't use fr_opcode[2] because this may be
2573 in a different frag. */
2574 buffer_address[0] = M6811_JMP;
2577 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
2578 fragP->fr_offset, 0, BFD_RELOC_16);
2584 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_UNDF):
2585 assert (current_architecture & cpu6812);
2587 if (S_GET_SEGMENT (fragP->fr_symbol) == segment)
2589 fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_OFFSET,
2594 /* Switch the indexed operation to 16-bit mode. */
2595 if ((fragP->fr_opcode[1] & 0x21) == 0x20)
2596 fragP->fr_opcode[1] = (fragP->fr_opcode[1] >> 3) | 0xc0 | 0x02;
2599 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
2600 fragP->fr_offset, 0, BFD_RELOC_16);
2606 case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_UNDF):
2607 assert (current_architecture & cpu6812);
2609 if (S_GET_SEGMENT (fragP->fr_symbol) == segment)
2611 fragP->fr_subtype = ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_BYTE);
2615 fragP->fr_opcode[0] ^= 0x20; /* Reverse sense of branch. */
2616 fragP->fr_opcode[1] = 3; /* Skip next jmp insn (3 bytes). */
2618 /* Don't use fr_opcode[2] because this may be
2619 in a different frag. */
2620 buffer_address[0] = M6812_JMP;
2623 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
2624 fragP->fr_offset, 0, BFD_RELOC_16);
2630 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_UNDF):
2631 assert (current_architecture & cpu6812);
2633 if (S_GET_SEGMENT (fragP->fr_symbol) == segment)
2635 fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812,
2640 /* Translate into a lbcc branch. */
2641 fragP->fr_opcode[1] = fragP->fr_opcode[0];
2642 fragP->fr_opcode[0] = M6811_OPCODE_PAGE2;
2644 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
2645 fragP->fr_offset, 0, BFD_RELOC_16_PCREL);
2652 as_fatal (_("Subtype %d is not recognized."), fragP->fr_subtype);
2655 return (fragP->fr_fix - old_fr_fix);
2659 md_apply_fix (fixp, valuep)
2667 if (fixp->fx_addsy == (symbolS *) NULL)
2672 else if (fixp->fx_pcrel)
2678 value = fixp->fx_offset;
2679 if (fixp->fx_subsy != (symbolS *) NULL)
2681 if (S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
2683 value -= S_GET_VALUE (fixp->fx_subsy);
2687 /* We don't actually support subtracting a symbol. */
2688 as_bad_where (fixp->fx_file, fixp->fx_line,
2689 _("Expression too complex."));
2694 op_type = fixp->fx_r_type;
2696 /* Patch the instruction with the resolved operand. Elf relocation
2697 info will also be generated to take care of linker/loader fixups.
2698 The 68HC11 addresses only 64Kb, we are only concerned by 8 and 16-bit
2699 relocs. BFD_RELOC_8 is basically used for .page0 access (the linker
2700 will warn for overflows). BFD_RELOC_8_PCREL should not be generated
2701 because it's either resolved or turned out into non-relative insns (see
2702 relax table, bcc, bra, bsr transformations)
2704 The BFD_RELOC_32 is necessary for the support of --gstabs. */
2705 where = fixp->fx_frag->fr_literal + fixp->fx_where;
2707 switch (fixp->fx_r_type)
2710 bfd_putb32 ((bfd_vma) value, (unsigned char *) where);
2714 case BFD_RELOC_16_PCREL:
2715 bfd_putb16 ((bfd_vma) value, (unsigned char *) where);
2716 if (value < -65537 || value > 65535)
2717 as_bad_where (fixp->fx_file, fixp->fx_line,
2718 _("Value out of 16-bit range."));
2721 case BFD_RELOC_M68HC11_HI8:
2725 case BFD_RELOC_M68HC11_LO8:
2728 bfd_putb8 ((bfd_vma) value, (unsigned char *) where);
2730 ((bfd_byte *) where)[0] = (bfd_byte) value;
2733 case BFD_RELOC_8_PCREL:
2735 bfd_putb8 ((bfd_vma) value, (unsigned char *) where);
2737 ((bfd_byte *) where)[0] = (bfd_byte) value;
2739 if (value < -128 || value > 127)
2740 as_bad_where (fixp->fx_file, fixp->fx_line,
2741 _("Value %ld too large for 8-bit PC-relative branch."),
2745 case BFD_RELOC_M68HC11_3B:
2746 if (value <= 0 || value > 8)
2747 as_bad_where (fixp->fx_file, fixp->fx_line,
2748 _("Auto increment/decrement offset '%ld' is out of range."),
2755 where[0] = where[0] | (value & 0x07);
2759 as_fatal (_("Line %d: unknown relocation type: 0x%x."),
2760 fixp->fx_line, fixp->fx_r_type);
2773 m68hc11_end_of_source ()
2776 subsegT saved_subseg;
2779 long total_size = 0;
2781 if (debug_type != DEBUG_DWARF2)
2786 saved_seg = now_seg;
2787 saved_subseg = now_subseg;
2789 debug_info = subseg_new (".debug_info", 0);
2790 bfd_set_section_flags (stdoutput, debug_info, SEC_READONLY);
2791 subseg_set (debug_info, 0);
2795 # define STUFF(val,size) md_number_to_chars (p, val, size); p += size;
2796 STUFF (total_size, 4); /* Length of compilation unit. */
2797 STUFF (2, 2); /* Dwarf version */
2799 STUFF (2, 1); /* Pointer size */
2800 STUFF (1, 1); /* Compile unit */
2803 now_subseg = saved_subseg;
2804 now_seg = saved_seg;