2008-09-30 H.J. Lu <hongjiu.lu@intel.com>
[binutils.git] / gas / config / tc-m68hc11.c
blobdde6a37b5631728ff297241e1252b17ff6e1da85
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 3, 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, 8 + 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 char *
518 md_atof (int type, char *litP, int *sizeP)
520 return ieee_md_atof (type, litP, sizeP, TRUE);
523 valueT
524 md_section_align (asection *seg, valueT addr)
526 int align = bfd_get_section_alignment (stdoutput, seg);
527 return ((addr + (1 << align) - 1) & (-1 << align));
530 static int
531 cmp_opcode (struct m68hc11_opcode *op1, struct m68hc11_opcode *op2)
533 return strcmp (op1->name, op2->name);
536 #define IS_CALL_SYMBOL(MODE) \
537 (((MODE) & (M6812_OP_PAGE|M6811_OP_IND16)) \
538 == ((M6812_OP_PAGE|M6811_OP_IND16)))
540 /* Initialize the assembler. Create the opcode hash table
541 (sorted on the names) with the M6811 opcode table
542 (from opcode library). */
543 void
544 md_begin (void)
546 char *prev_name = "";
547 struct m68hc11_opcode *opcodes;
548 struct m68hc11_opcode_def *opc = 0;
549 int i, j;
551 get_default_target ();
553 m68hc11_hash = hash_new ();
555 /* Get a writable copy of the opcode table and sort it on the names. */
556 opcodes = (struct m68hc11_opcode *) xmalloc (m68hc11_num_opcodes *
557 sizeof (struct
558 m68hc11_opcode));
559 m68hc11_sorted_opcodes = opcodes;
560 num_opcodes = 0;
561 for (i = 0; i < m68hc11_num_opcodes; i++)
563 if (m68hc11_opcodes[i].arch & current_architecture)
565 opcodes[num_opcodes] = m68hc11_opcodes[i];
566 if (opcodes[num_opcodes].name[0] == 'b'
567 && opcodes[num_opcodes].format & M6811_OP_JUMP_REL
568 && !(opcodes[num_opcodes].format & M6811_OP_BITMASK))
570 num_opcodes++;
571 opcodes[num_opcodes] = m68hc11_opcodes[i];
573 num_opcodes++;
574 for (j = 0; alias_opcodes[j].name != 0; j++)
575 if (strcmp (m68hc11_opcodes[i].name, alias_opcodes[j].name) == 0)
577 opcodes[num_opcodes] = m68hc11_opcodes[i];
578 opcodes[num_opcodes].name = alias_opcodes[j].alias;
579 num_opcodes++;
580 break;
584 qsort (opcodes, num_opcodes, sizeof (struct m68hc11_opcode),
585 (int (*) (const void*, const void*)) cmp_opcode);
587 opc = (struct m68hc11_opcode_def *)
588 xmalloc (num_opcodes * sizeof (struct m68hc11_opcode_def));
589 m68hc11_opcode_defs = opc--;
591 /* Insert unique names into hash table. The M6811 instruction set
592 has several identical opcode names that have different opcodes based
593 on the operands. This hash table then provides a quick index to
594 the first opcode with a particular name in the opcode table. */
595 for (i = 0; i < num_opcodes; i++, opcodes++)
597 int expect;
599 if (strcmp (prev_name, opcodes->name))
601 prev_name = (char *) opcodes->name;
603 opc++;
604 opc->format = 0;
605 opc->min_operands = 100;
606 opc->max_operands = 0;
607 opc->nb_modes = 0;
608 opc->opcode = opcodes;
609 opc->used = 0;
610 hash_insert (m68hc11_hash, opcodes->name, opc);
612 opc->nb_modes++;
613 opc->format |= opcodes->format;
615 /* See how many operands this opcode needs. */
616 expect = 0;
617 if (opcodes->format & M6811_OP_MASK)
618 expect++;
619 if (opcodes->format & M6811_OP_BITMASK)
620 expect++;
621 if (opcodes->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
622 expect++;
623 if (opcodes->format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2))
624 expect++;
625 /* Special case for call instruction. */
626 if ((opcodes->format & M6812_OP_PAGE)
627 && !(opcodes->format & M6811_OP_IND16))
628 expect++;
630 if (expect < opc->min_operands)
631 opc->min_operands = expect;
632 if (IS_CALL_SYMBOL (opcodes->format))
633 expect++;
634 if (expect > opc->max_operands)
635 opc->max_operands = expect;
637 opc++;
638 m68hc11_nb_opcode_defs = opc - m68hc11_opcode_defs;
640 if (flag_print_opcodes)
642 print_opcode_list ();
643 exit (EXIT_SUCCESS);
647 void
648 m68hc11_init_after_args (void)
652 /* Builtin help. */
654 /* Return a string that represents the operand format for the instruction.
655 When example is true, this generates an example of operand. This is used
656 to give an example and also to generate a test. */
657 static char *
658 print_opcode_format (struct m68hc11_opcode *opcode, int example)
660 static char buf[128];
661 int format = opcode->format;
662 char *p;
664 p = buf;
665 buf[0] = 0;
666 if (format & M6811_OP_IMM8)
668 if (example)
669 sprintf (p, "#%d", rand () & 0x0FF);
670 else
671 strcpy (p, _("#<imm8>"));
672 p = &p[strlen (p)];
675 if (format & M6811_OP_IMM16)
677 if (example)
678 sprintf (p, "#%d", rand () & 0x0FFFF);
679 else
680 strcpy (p, _("#<imm16>"));
681 p = &p[strlen (p)];
684 if (format & M6811_OP_IX)
686 if (example)
687 sprintf (p, "%d,X", rand () & 0x0FF);
688 else
689 strcpy (p, _("<imm8>,X"));
690 p = &p[strlen (p)];
693 if (format & M6811_OP_IY)
695 if (example)
696 sprintf (p, "%d,X", rand () & 0x0FF);
697 else
698 strcpy (p, _("<imm8>,X"));
699 p = &p[strlen (p)];
702 if (format & M6812_OP_IDX)
704 if (example)
705 sprintf (p, "%d,X", rand () & 0x0FF);
706 else
707 strcpy (p, "n,r");
708 p = &p[strlen (p)];
711 if (format & M6812_OP_PAGE)
713 if (example)
714 sprintf (p, ", %d", rand () & 0x0FF);
715 else
716 strcpy (p, ", <page>");
717 p = &p[strlen (p)];
720 if (format & M6811_OP_DIRECT)
722 if (example)
723 sprintf (p, "*Z%d", rand () & 0x0FF);
724 else
725 strcpy (p, _("*<abs8>"));
726 p = &p[strlen (p)];
729 if (format & M6811_OP_BITMASK)
731 if (buf[0])
732 *p++ = ' ';
734 if (example)
735 sprintf (p, "#$%02x", rand () & 0x0FF);
736 else
737 strcpy (p, _("#<mask>"));
739 p = &p[strlen (p)];
740 if (format & M6811_OP_JUMP_REL)
741 *p++ = ' ';
744 if (format & M6811_OP_IND16)
746 if (example)
747 sprintf (p, _("symbol%d"), rand () & 0x0FF);
748 else
749 strcpy (p, _("<abs>"));
751 p = &p[strlen (p)];
754 if (format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
756 if (example)
758 if (format & M6811_OP_BITMASK)
760 sprintf (p, ".+%d", rand () & 0x7F);
762 else
764 sprintf (p, "L%d", rand () & 0x0FF);
767 else
768 strcpy (p, _("<label>"));
771 return buf;
774 /* Prints the list of instructions with the possible operands. */
775 static void
776 print_opcode_list (void)
778 int i;
779 char *prev_name = "";
780 struct m68hc11_opcode *opcodes;
781 int example = flag_print_opcodes == 2;
783 if (example)
784 printf (_("# Example of `%s' instructions\n\t.sect .text\n_start:\n"),
785 default_cpu);
787 opcodes = m68hc11_sorted_opcodes;
789 /* Walk the list sorted on names (by md_begin). We only report
790 one instruction per line, and we collect the different operand
791 formats. */
792 for (i = 0; i < num_opcodes; i++, opcodes++)
794 char *fmt = print_opcode_format (opcodes, example);
796 if (example)
798 printf ("L%d:\t", i);
799 printf ("%s %s\n", opcodes->name, fmt);
801 else
803 if (strcmp (prev_name, opcodes->name))
805 if (i > 0)
806 printf ("\n");
808 printf ("%-5.5s ", opcodes->name);
809 prev_name = (char *) opcodes->name;
811 if (fmt[0])
812 printf (" [%s]", fmt);
815 printf ("\n");
818 /* Print the instruction format. This operation is called when some
819 instruction is not correct. Instruction format is printed as an
820 error message. */
821 static void
822 print_insn_format (char *name)
824 struct m68hc11_opcode_def *opc;
825 struct m68hc11_opcode *opcode;
826 char buf[128];
828 opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash, name);
829 if (opc == NULL)
831 as_bad (_("Instruction `%s' is not recognized."), name);
832 return;
834 opcode = opc->opcode;
836 as_bad (_("Instruction formats for `%s':"), name);
839 char *fmt;
841 fmt = print_opcode_format (opcode, 0);
842 sprintf (buf, "\t%-5.5s %s", opcode->name, fmt);
844 as_bad ("%s", buf);
845 opcode++;
847 while (strcmp (opcode->name, name) == 0);
850 /* Analysis of 68HC11 and 68HC12 operands. */
852 /* reg_name_search() finds the register number given its name.
853 Returns the register number or REG_NONE on failure. */
854 static register_id
855 reg_name_search (char *name)
857 if (strcasecmp (name, "x") == 0 || strcasecmp (name, "ix") == 0)
858 return REG_X;
859 if (strcasecmp (name, "y") == 0 || strcasecmp (name, "iy") == 0)
860 return REG_Y;
861 if (strcasecmp (name, "a") == 0)
862 return REG_A;
863 if (strcasecmp (name, "b") == 0)
864 return REG_B;
865 if (strcasecmp (name, "d") == 0)
866 return REG_D;
867 if (strcasecmp (name, "sp") == 0)
868 return REG_SP;
869 if (strcasecmp (name, "pc") == 0)
870 return REG_PC;
871 if (strcasecmp (name, "ccr") == 0)
872 return REG_CCR;
874 return REG_NONE;
877 static char *
878 skip_whites (char *p)
880 while (*p == ' ' || *p == '\t')
881 p++;
883 return p;
886 /* Check the string at input_line_pointer
887 to see if it is a valid register name. */
888 static register_id
889 register_name (void)
891 register_id reg_number;
892 char c, *p = input_line_pointer;
894 if (!is_name_beginner (*p++))
895 return REG_NONE;
897 while (is_part_of_name (*p++))
898 continue;
900 c = *--p;
901 if (c)
902 *p++ = 0;
904 /* Look to see if it's in the register table. */
905 reg_number = reg_name_search (input_line_pointer);
906 if (reg_number != REG_NONE)
908 if (c)
909 *--p = c;
911 input_line_pointer = p;
912 return reg_number;
914 if (c)
915 *--p = c;
917 return reg_number;
919 #define M6811_OP_CALL_ADDR 0x00800000
920 #define M6811_OP_PAGE_ADDR 0x04000000
922 /* Parse a string of operands and return an array of expressions.
924 Operand mode[0] mode[1] exp[0] exp[1]
925 #n M6811_OP_IMM16 - O_*
926 *<exp> M6811_OP_DIRECT - O_*
927 .{+-}<exp> M6811_OP_JUMP_REL - O_*
928 <exp> M6811_OP_IND16 - O_*
929 ,r N,r M6812_OP_IDX M6812_OP_REG O_constant O_register
930 n,-r M6812_PRE_DEC M6812_OP_REG O_constant O_register
931 n,+r M6812_PRE_INC " "
932 n,r- M6812_POST_DEC " "
933 n,r+ M6812_POST_INC " "
934 A,r B,r D,r M6811_OP_REG M6812_OP_REG O_register O_register
935 [D,r] M6811_OP_D_IDX M6812_OP_REG O_register O_register
936 [n,r] M6811_OP_D_IDX_2 M6812_OP_REG O_constant O_register */
937 static int
938 get_operand (operand *oper, int which, long opmode)
940 char *p = input_line_pointer;
941 int mode;
942 register_id reg;
944 oper->exp.X_op = O_absent;
945 oper->reg1 = REG_NONE;
946 oper->reg2 = REG_NONE;
947 mode = M6811_OP_NONE;
949 p = skip_whites (p);
951 if (*p == 0 || *p == '\n' || *p == '\r')
953 input_line_pointer = p;
954 return 0;
957 if (*p == '*' && (opmode & (M6811_OP_DIRECT | M6811_OP_IND16)))
959 mode = M6811_OP_DIRECT;
960 p++;
962 else if (*p == '#')
964 if (!(opmode & (M6811_OP_IMM8 | M6811_OP_IMM16 | M6811_OP_BITMASK)))
966 as_bad (_("Immediate operand is not allowed for operand %d."),
967 which);
968 return -1;
971 mode = M6811_OP_IMM16;
972 p++;
973 if (strncmp (p, "%hi", 3) == 0)
975 p += 3;
976 mode |= M6811_OP_HIGH_ADDR;
978 else if (strncmp (p, "%lo", 3) == 0)
980 p += 3;
981 mode |= M6811_OP_LOW_ADDR;
983 /* %page modifier is used to obtain only the page number
984 of the address of a function. */
985 else if (strncmp (p, "%page", 5) == 0)
987 p += 5;
988 mode |= M6811_OP_PAGE_ADDR;
991 /* %addr modifier is used to obtain the physical address part
992 of the function (16-bit). For 68HC12 the function will be
993 mapped in the 16K window at 0x8000 and the value will be
994 within that window (although the function address may not fit
995 in 16-bit). See bfd/elf32-m68hc12.c for the translation. */
996 else if (strncmp (p, "%addr", 5) == 0)
998 p += 5;
999 mode |= M6811_OP_CALL_ADDR;
1002 else if (*p == '.' && (p[1] == '+' || p[1] == '-'))
1004 p++;
1005 mode = M6811_OP_JUMP_REL;
1007 else if (*p == '[')
1009 if (current_architecture & cpu6811)
1010 as_bad (_("Indirect indexed addressing is not valid for 68HC11."));
1012 p++;
1013 mode = M6812_OP_D_IDX;
1014 p = skip_whites (p);
1016 else if (*p == ',') /* Special handling of ,x and ,y. */
1018 p++;
1019 input_line_pointer = p;
1021 reg = register_name ();
1022 if (reg != REG_NONE)
1024 oper->reg1 = reg;
1025 oper->exp.X_op = O_constant;
1026 oper->exp.X_add_number = 0;
1027 oper->mode = M6812_OP_IDX;
1028 return 1;
1030 as_bad (_("Spurious `,' or bad indirect register addressing mode."));
1031 return -1;
1033 /* Handle 68HC12 page specification in 'call foo,%page(bar)'. */
1034 else if ((opmode & M6812_OP_PAGE) && strncmp (p, "%page", 5) == 0)
1036 p += 5;
1037 mode = M6811_OP_PAGE_ADDR | M6812_OP_PAGE | M6811_OP_IND16;
1039 input_line_pointer = p;
1041 if (mode == M6811_OP_NONE || mode == M6812_OP_D_IDX)
1042 reg = register_name ();
1043 else
1044 reg = REG_NONE;
1046 if (reg != REG_NONE)
1048 p = skip_whites (input_line_pointer);
1049 if (*p == ']' && mode == M6812_OP_D_IDX)
1051 as_bad
1052 (_("Missing second register or offset for indexed-indirect mode."));
1053 return -1;
1056 oper->reg1 = reg;
1057 oper->mode = mode | M6812_OP_REG;
1058 if (*p != ',')
1060 if (mode == M6812_OP_D_IDX)
1062 as_bad (_("Missing second register for indexed-indirect mode."));
1063 return -1;
1065 return 1;
1068 p++;
1069 input_line_pointer = p;
1070 reg = register_name ();
1071 if (reg != REG_NONE)
1073 p = skip_whites (input_line_pointer);
1074 if (mode == M6812_OP_D_IDX)
1076 if (*p != ']')
1078 as_bad (_("Missing `]' to close indexed-indirect mode."));
1079 return -1;
1081 p++;
1082 oper->mode = M6812_OP_D_IDX;
1084 input_line_pointer = p;
1086 oper->reg2 = reg;
1087 return 1;
1089 return 1;
1092 /* In MRI mode, isolate the operand because we can't distinguish
1093 operands from comments. */
1094 if (flag_mri)
1096 char c = 0;
1098 p = skip_whites (p);
1099 while (*p && *p != ' ' && *p != '\t')
1100 p++;
1102 if (*p)
1104 c = *p;
1105 *p = 0;
1108 /* Parse as an expression. */
1109 expression (&oper->exp);
1111 if (c)
1113 *p = c;
1116 else
1118 expression (&oper->exp);
1121 if (oper->exp.X_op == O_illegal)
1123 as_bad (_("Illegal operand."));
1124 return -1;
1126 else if (oper->exp.X_op == O_absent)
1128 as_bad (_("Missing operand."));
1129 return -1;
1132 p = input_line_pointer;
1134 if (mode == M6811_OP_NONE || mode == M6811_OP_DIRECT
1135 || mode == M6812_OP_D_IDX)
1137 p = skip_whites (input_line_pointer);
1139 if (*p == ',')
1141 int possible_mode = M6811_OP_NONE;
1142 char *old_input_line;
1144 old_input_line = p;
1145 p++;
1147 /* 68HC12 pre increment or decrement. */
1148 if (mode == M6811_OP_NONE)
1150 if (*p == '-')
1152 possible_mode = M6812_PRE_DEC;
1153 p++;
1155 else if (*p == '+')
1157 possible_mode = M6812_PRE_INC;
1158 p++;
1160 p = skip_whites (p);
1162 input_line_pointer = p;
1163 reg = register_name ();
1165 /* Backtrack if we have a valid constant expression and
1166 it does not correspond to the offset of the 68HC12 indexed
1167 addressing mode (as in N,x). */
1168 if (reg == REG_NONE && mode == M6811_OP_NONE
1169 && possible_mode != M6811_OP_NONE)
1171 oper->mode = M6811_OP_IND16 | M6811_OP_JUMP_REL;
1172 input_line_pointer = skip_whites (old_input_line);
1173 return 1;
1176 if (possible_mode != M6811_OP_NONE)
1177 mode = possible_mode;
1179 if ((current_architecture & cpu6811)
1180 && possible_mode != M6811_OP_NONE)
1181 as_bad (_("Pre-increment mode is not valid for 68HC11"));
1182 /* Backtrack. */
1183 if (which == 0 && opmode & M6812_OP_IDX_P2
1184 && reg != REG_X && reg != REG_Y
1185 && reg != REG_PC && reg != REG_SP)
1187 reg = REG_NONE;
1188 input_line_pointer = p;
1191 if (reg == REG_NONE && mode != M6811_OP_DIRECT
1192 && !(mode == M6811_OP_NONE && opmode & M6811_OP_IND16))
1194 as_bad (_("Wrong register in register indirect mode."));
1195 return -1;
1197 if (mode == M6812_OP_D_IDX)
1199 p = skip_whites (input_line_pointer);
1200 if (*p++ != ']')
1202 as_bad (_("Missing `]' to close register indirect operand."));
1203 return -1;
1205 input_line_pointer = p;
1206 oper->reg1 = reg;
1207 oper->mode = M6812_OP_D_IDX_2;
1208 return 1;
1210 if (reg != REG_NONE)
1212 oper->reg1 = reg;
1213 if (mode == M6811_OP_NONE)
1215 p = input_line_pointer;
1216 if (*p == '-')
1218 mode = M6812_POST_DEC;
1219 p++;
1220 if (current_architecture & cpu6811)
1221 as_bad
1222 (_("Post-decrement mode is not valid for 68HC11."));
1224 else if (*p == '+')
1226 mode = M6812_POST_INC;
1227 p++;
1228 if (current_architecture & cpu6811)
1229 as_bad
1230 (_("Post-increment mode is not valid for 68HC11."));
1232 else
1233 mode = M6812_OP_IDX;
1235 input_line_pointer = p;
1237 else
1238 mode |= M6812_OP_IDX;
1240 oper->mode = mode;
1241 return 1;
1243 input_line_pointer = old_input_line;
1246 if (mode == M6812_OP_D_IDX_2)
1248 as_bad (_("Invalid indexed indirect mode."));
1249 return -1;
1253 /* If the mode is not known until now, this is either a label
1254 or an indirect address. */
1255 if (mode == M6811_OP_NONE)
1256 mode = M6811_OP_IND16 | M6811_OP_JUMP_REL;
1258 p = input_line_pointer;
1259 while (*p == ' ' || *p == '\t')
1260 p++;
1261 input_line_pointer = p;
1262 oper->mode = mode;
1264 return 1;
1267 #define M6812_AUTO_INC_DEC (M6812_PRE_INC | M6812_PRE_DEC \
1268 | M6812_POST_INC | M6812_POST_DEC)
1270 /* Checks that the number 'num' fits for a given mode. */
1271 static int
1272 check_range (long num, int mode)
1274 /* Auto increment and decrement are ok for [-8..8] without 0. */
1275 if (mode & M6812_AUTO_INC_DEC)
1276 return (num != 0 && num <= 8 && num >= -8);
1278 /* The 68HC12 supports 5, 9 and 16-bit offsets. */
1279 if (mode & (M6812_INDEXED_IND | M6812_INDEXED | M6812_OP_IDX))
1280 mode = M6811_OP_IND16;
1282 if (mode & M6812_OP_JUMP_REL16)
1283 mode = M6811_OP_IND16;
1285 mode &= ~M6811_OP_BRANCH;
1286 switch (mode)
1288 case M6811_OP_IX:
1289 case M6811_OP_IY:
1290 case M6811_OP_DIRECT:
1291 return (num >= 0 && num <= 255) ? 1 : 0;
1293 case M6811_OP_BITMASK:
1294 case M6811_OP_IMM8:
1295 case M6812_OP_PAGE:
1296 return (((num & 0xFFFFFF00) == 0) || ((num & 0xFFFFFF00) == 0xFFFFFF00))
1297 ? 1 : 0;
1299 case M6811_OP_JUMP_REL:
1300 return (num >= -128 && num <= 127) ? 1 : 0;
1302 case M6811_OP_IND16:
1303 case M6811_OP_IND16 | M6812_OP_PAGE:
1304 case M6811_OP_IMM16:
1305 return (((num & 0xFFFF0000) == 0) || ((num & 0xFFFF0000) == 0xFFFF0000))
1306 ? 1 : 0;
1308 case M6812_OP_IBCC_MARKER:
1309 case M6812_OP_TBCC_MARKER:
1310 case M6812_OP_DBCC_MARKER:
1311 return (num >= -256 && num <= 255) ? 1 : 0;
1313 case M6812_OP_TRAP_ID:
1314 return ((num >= 0x30 && num <= 0x39)
1315 || (num >= 0x40 && num <= 0x0ff)) ? 1 : 0;
1317 default:
1318 return 0;
1322 /* Gas fixup generation. */
1324 /* Put a 1 byte expression described by 'oper'. If this expression contains
1325 unresolved symbols, generate an 8-bit fixup. */
1326 static void
1327 fixup8 (expressionS *oper, int mode, int opmode)
1329 char *f;
1331 f = frag_more (1);
1333 if (oper->X_op == O_constant)
1335 if (mode & M6812_OP_TRAP_ID
1336 && !check_range (oper->X_add_number, M6812_OP_TRAP_ID))
1338 static char trap_id_warn_once = 0;
1340 as_bad (_("Trap id `%ld' is out of range."), oper->X_add_number);
1341 if (trap_id_warn_once == 0)
1343 trap_id_warn_once = 1;
1344 as_bad (_("Trap id must be within [0x30..0x39] or [0x40..0xff]."));
1348 if (!(mode & M6812_OP_TRAP_ID)
1349 && !check_range (oper->X_add_number, mode))
1351 as_bad (_("Operand out of 8-bit range: `%ld'."), oper->X_add_number);
1353 number_to_chars_bigendian (f, oper->X_add_number & 0x0FF, 1);
1355 else if (oper->X_op != O_register)
1357 if (mode & M6812_OP_TRAP_ID)
1358 as_bad (_("The trap id must be a constant."));
1360 if (mode == M6811_OP_JUMP_REL)
1362 fixS *fixp;
1364 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
1365 oper, TRUE, BFD_RELOC_8_PCREL);
1366 fixp->fx_pcrel_adjust = 1;
1368 else
1370 fixS *fixp;
1371 int reloc;
1373 /* Now create an 8-bit fixup. If there was some %hi, %lo
1374 or %page modifier, generate the reloc accordingly. */
1375 if (opmode & M6811_OP_HIGH_ADDR)
1376 reloc = BFD_RELOC_M68HC11_HI8;
1377 else if (opmode & M6811_OP_LOW_ADDR)
1378 reloc = BFD_RELOC_M68HC11_LO8;
1379 else if (opmode & M6811_OP_PAGE_ADDR)
1380 reloc = BFD_RELOC_M68HC11_PAGE;
1381 else
1382 reloc = BFD_RELOC_8;
1384 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
1385 oper, FALSE, reloc);
1386 if (reloc != BFD_RELOC_8)
1387 fixp->fx_no_overflow = 1;
1389 number_to_chars_bigendian (f, 0, 1);
1391 else
1393 as_fatal (_("Operand `%x' not recognized in fixup8."), oper->X_op);
1397 /* Put a 2 byte expression described by 'oper'. If this expression contains
1398 unresolved symbols, generate a 16-bit fixup. */
1399 static void
1400 fixup16 (expressionS *oper, int mode, int opmode ATTRIBUTE_UNUSED)
1402 char *f;
1404 f = frag_more (2);
1406 if (oper->X_op == O_constant)
1408 if (!check_range (oper->X_add_number, mode))
1410 as_bad (_("Operand out of 16-bit range: `%ld'."),
1411 oper->X_add_number);
1413 number_to_chars_bigendian (f, oper->X_add_number & 0x0FFFF, 2);
1415 else if (oper->X_op != O_register)
1417 fixS *fixp;
1418 int reloc;
1420 if ((opmode & M6811_OP_CALL_ADDR) && (mode & M6811_OP_IMM16))
1421 reloc = BFD_RELOC_M68HC11_LO16;
1422 else if (mode & M6812_OP_JUMP_REL16)
1423 reloc = BFD_RELOC_16_PCREL;
1424 else if (mode & M6812_OP_PAGE)
1425 reloc = BFD_RELOC_M68HC11_LO16;
1426 else
1427 reloc = BFD_RELOC_16;
1429 /* Now create a 16-bit fixup. */
1430 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 2,
1431 oper,
1432 reloc == BFD_RELOC_16_PCREL,
1433 reloc);
1434 number_to_chars_bigendian (f, 0, 2);
1435 if (reloc == BFD_RELOC_16_PCREL)
1436 fixp->fx_pcrel_adjust = 2;
1437 if (reloc == BFD_RELOC_M68HC11_LO16)
1438 fixp->fx_no_overflow = 1;
1440 else
1442 as_fatal (_("Operand `%x' not recognized in fixup16."), oper->X_op);
1446 /* Put a 3 byte expression described by 'oper'. If this expression contains
1447 unresolved symbols, generate a 24-bit fixup. */
1448 static void
1449 fixup24 (expressionS *oper, int mode, int opmode ATTRIBUTE_UNUSED)
1451 char *f;
1453 f = frag_more (3);
1455 if (oper->X_op == O_constant)
1457 if (!check_range (oper->X_add_number, mode))
1459 as_bad (_("Operand out of 16-bit range: `%ld'."),
1460 oper->X_add_number);
1462 number_to_chars_bigendian (f, oper->X_add_number & 0x0FFFFFF, 3);
1464 else if (oper->X_op != O_register)
1466 fixS *fixp;
1468 /* Now create a 24-bit fixup. */
1469 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 3,
1470 oper, FALSE, BFD_RELOC_M68HC11_24);
1471 number_to_chars_bigendian (f, 0, 3);
1473 else
1475 as_fatal (_("Operand `%x' not recognized in fixup16."), oper->X_op);
1479 /* 68HC11 and 68HC12 code generation. */
1481 /* Translate the short branch/bsr instruction into a long branch. */
1482 static unsigned char
1483 convert_branch (unsigned char code)
1485 if (IS_OPCODE (code, M6812_BSR))
1486 return M6812_JSR;
1487 else if (IS_OPCODE (code, M6811_BSR))
1488 return M6811_JSR;
1489 else if (IS_OPCODE (code, M6811_BRA))
1490 return (current_architecture & cpu6812) ? M6812_JMP : M6811_JMP;
1491 else
1492 as_fatal (_("Unexpected branch conversion with `%x'"), code);
1494 /* Keep gcc happy. */
1495 return M6811_JSR;
1498 /* Start a new insn that contains at least 'size' bytes. Record the
1499 line information of that insn in the dwarf2 debug sections. */
1500 static char *
1501 m68hc11_new_insn (int size)
1503 char *f;
1505 f = frag_more (size);
1507 dwarf2_emit_insn (size);
1509 return f;
1512 /* Builds a jump instruction (bra, bcc, bsr). */
1513 static void
1514 build_jump_insn (struct m68hc11_opcode *opcode, operand operands[],
1515 int nb_operands, int jmp_mode)
1517 unsigned char code;
1518 char *f;
1519 unsigned long n;
1520 fragS *frag;
1521 int where;
1523 /* The relative branch conversion is not supported for
1524 brclr and brset. */
1525 assert ((opcode->format & M6811_OP_BITMASK) == 0);
1526 assert (nb_operands == 1);
1527 assert (operands[0].reg1 == REG_NONE && operands[0].reg2 == REG_NONE);
1529 code = opcode->opcode;
1531 n = operands[0].exp.X_add_number;
1533 /* Turn into a long branch:
1534 - when force long branch option (and not for jbcc pseudos),
1535 - when jbcc and the constant is out of -128..127 range,
1536 - when branch optimization is allowed and branch out of range. */
1537 if ((jmp_mode == 0 && flag_force_long_jumps)
1538 || (operands[0].exp.X_op == O_constant
1539 && (!check_range (n, opcode->format) &&
1540 (jmp_mode == 1 || flag_fixed_branches == 0))))
1542 frag = frag_now;
1543 where = frag_now_fix ();
1545 fix_new (frag_now, frag_now_fix (), 0,
1546 &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
1548 if (code == M6811_BSR || code == M6811_BRA || code == M6812_BSR)
1550 code = convert_branch (code);
1552 f = m68hc11_new_insn (1);
1553 number_to_chars_bigendian (f, code, 1);
1555 else if (current_architecture & cpu6812)
1557 /* 68HC12: translate the bcc into a lbcc. */
1558 f = m68hc11_new_insn (2);
1559 number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1);
1560 number_to_chars_bigendian (f + 1, code, 1);
1561 fixup16 (&operands[0].exp, M6812_OP_JUMP_REL16,
1562 M6812_OP_JUMP_REL16);
1563 return;
1565 else
1567 /* 68HC11: translate the bcc into b!cc +3; jmp <L>. */
1568 f = m68hc11_new_insn (3);
1569 code ^= 1;
1570 number_to_chars_bigendian (f, code, 1);
1571 number_to_chars_bigendian (f + 1, 3, 1);
1572 number_to_chars_bigendian (f + 2, M6811_JMP, 1);
1574 fixup16 (&operands[0].exp, M6811_OP_IND16, M6811_OP_IND16);
1575 return;
1578 /* Branch with a constant that must fit in 8-bits. */
1579 if (operands[0].exp.X_op == O_constant)
1581 if (!check_range (n, opcode->format))
1583 as_bad (_("Operand out of range for a relative branch: `%ld'"),
1586 else if (opcode->format & M6812_OP_JUMP_REL16)
1588 f = m68hc11_new_insn (4);
1589 number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1);
1590 number_to_chars_bigendian (f + 1, code, 1);
1591 number_to_chars_bigendian (f + 2, n & 0x0ffff, 2);
1593 else
1595 f = m68hc11_new_insn (2);
1596 number_to_chars_bigendian (f, code, 1);
1597 number_to_chars_bigendian (f + 1, n & 0x0FF, 1);
1600 else if (opcode->format & M6812_OP_JUMP_REL16)
1602 frag = frag_now;
1603 where = frag_now_fix ();
1605 fix_new (frag_now, frag_now_fix (), 0,
1606 &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
1608 f = m68hc11_new_insn (2);
1609 number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1);
1610 number_to_chars_bigendian (f + 1, code, 1);
1611 fixup16 (&operands[0].exp, M6812_OP_JUMP_REL16, M6812_OP_JUMP_REL16);
1613 else
1615 char *opcode;
1617 frag = frag_now;
1618 where = frag_now_fix ();
1620 fix_new (frag_now, frag_now_fix (), 0,
1621 &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
1623 /* Branch offset must fit in 8-bits, don't do some relax. */
1624 if (jmp_mode == 0 && flag_fixed_branches)
1626 opcode = m68hc11_new_insn (1);
1627 number_to_chars_bigendian (opcode, code, 1);
1628 fixup8 (&operands[0].exp, M6811_OP_JUMP_REL, M6811_OP_JUMP_REL);
1631 /* bra/bsr made be changed into jmp/jsr. */
1632 else if (code == M6811_BSR || code == M6811_BRA || code == M6812_BSR)
1634 /* Allocate worst case storage. */
1635 opcode = m68hc11_new_insn (3);
1636 number_to_chars_bigendian (opcode, code, 1);
1637 number_to_chars_bigendian (opcode + 1, 0, 1);
1638 frag_variant (rs_machine_dependent, 1, 1,
1639 ENCODE_RELAX (STATE_PC_RELATIVE, STATE_UNDF),
1640 operands[0].exp.X_add_symbol, (offsetT) n,
1641 opcode);
1643 else if (current_architecture & cpu6812)
1645 opcode = m68hc11_new_insn (2);
1646 number_to_chars_bigendian (opcode, code, 1);
1647 number_to_chars_bigendian (opcode + 1, 0, 1);
1648 frag_var (rs_machine_dependent, 2, 2,
1649 ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_UNDF),
1650 operands[0].exp.X_add_symbol, (offsetT) n, opcode);
1652 else
1654 opcode = m68hc11_new_insn (2);
1655 number_to_chars_bigendian (opcode, code, 1);
1656 number_to_chars_bigendian (opcode + 1, 0, 1);
1657 frag_var (rs_machine_dependent, 3, 3,
1658 ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_UNDF),
1659 operands[0].exp.X_add_symbol, (offsetT) n, opcode);
1664 /* Builds a dbne/dbeq/tbne/tbeq instruction. */
1665 static void
1666 build_dbranch_insn (struct m68hc11_opcode *opcode, operand operands[],
1667 int nb_operands, int jmp_mode)
1669 unsigned char code;
1670 char *f;
1671 unsigned long n;
1673 /* The relative branch conversion is not supported for
1674 brclr and brset. */
1675 assert ((opcode->format & M6811_OP_BITMASK) == 0);
1676 assert (nb_operands == 2);
1677 assert (operands[0].reg1 != REG_NONE);
1679 code = opcode->opcode & 0x0FF;
1681 f = m68hc11_new_insn (1);
1682 number_to_chars_bigendian (f, code, 1);
1684 n = operands[1].exp.X_add_number;
1685 code = operands[0].reg1;
1687 if (operands[0].reg1 == REG_NONE || operands[0].reg1 == REG_CCR
1688 || operands[0].reg1 == REG_PC)
1689 as_bad (_("Invalid register for dbcc/tbcc instruction."));
1691 if (opcode->format & M6812_OP_IBCC_MARKER)
1692 code |= 0x80;
1693 else if (opcode->format & M6812_OP_TBCC_MARKER)
1694 code |= 0x40;
1696 if (!(opcode->format & M6812_OP_EQ_MARKER))
1697 code |= 0x20;
1699 /* Turn into a long branch:
1700 - when force long branch option (and not for jbcc pseudos),
1701 - when jdbcc and the constant is out of -256..255 range,
1702 - when branch optimization is allowed and branch out of range. */
1703 if ((jmp_mode == 0 && flag_force_long_jumps)
1704 || (operands[1].exp.X_op == O_constant
1705 && (!check_range (n, M6812_OP_IBCC_MARKER) &&
1706 (jmp_mode == 1 || flag_fixed_branches == 0))))
1708 f = frag_more (2);
1709 code ^= 0x20;
1710 number_to_chars_bigendian (f, code, 1);
1711 number_to_chars_bigendian (f + 1, M6812_JMP, 1);
1712 fixup16 (&operands[0].exp, M6811_OP_IND16, M6811_OP_IND16);
1713 return;
1716 /* Branch with a constant that must fit in 9-bits. */
1717 if (operands[1].exp.X_op == O_constant)
1719 if (!check_range (n, M6812_OP_IBCC_MARKER))
1721 as_bad (_("Operand out of range for a relative branch: `%ld'"),
1724 else
1726 if ((long) n < 0)
1727 code |= 0x10;
1729 f = frag_more (2);
1730 number_to_chars_bigendian (f, code, 1);
1731 number_to_chars_bigendian (f + 1, n & 0x0FF, 1);
1734 else
1736 /* Branch offset must fit in 8-bits, don't do some relax. */
1737 if (jmp_mode == 0 && flag_fixed_branches)
1739 fixup8 (&operands[0].exp, M6811_OP_JUMP_REL, M6811_OP_JUMP_REL);
1742 else
1744 f = frag_more (2);
1745 number_to_chars_bigendian (f, code, 1);
1746 number_to_chars_bigendian (f + 1, 0, 1);
1747 frag_var (rs_machine_dependent, 3, 3,
1748 ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_UNDF),
1749 operands[1].exp.X_add_symbol, (offsetT) n, f);
1754 #define OP_EXTENDED (M6811_OP_PAGE2 | M6811_OP_PAGE3 | M6811_OP_PAGE4)
1756 /* Assemble the post index byte for 68HC12 extended addressing modes. */
1757 static int
1758 build_indexed_byte (operand *op, int format ATTRIBUTE_UNUSED, int move_insn)
1760 unsigned char byte = 0;
1761 char *f;
1762 int mode;
1763 long val;
1765 val = op->exp.X_add_number;
1766 mode = op->mode;
1767 if (mode & M6812_AUTO_INC_DEC)
1769 byte = 0x20;
1770 if (mode & (M6812_POST_INC | M6812_POST_DEC))
1771 byte |= 0x10;
1773 if (op->exp.X_op == O_constant)
1775 if (!check_range (val, mode))
1777 as_bad (_("Increment/decrement value is out of range: `%ld'."),
1778 val);
1780 if (mode & (M6812_POST_INC | M6812_PRE_INC))
1781 byte |= (val - 1) & 0x07;
1782 else
1783 byte |= (8 - ((val) & 7)) | 0x8;
1785 switch (op->reg1)
1787 case REG_NONE:
1788 as_fatal (_("Expecting a register."));
1790 case REG_X:
1791 byte |= 0;
1792 break;
1794 case REG_Y:
1795 byte |= 0x40;
1796 break;
1798 case REG_SP:
1799 byte |= 0x80;
1800 break;
1802 default:
1803 as_bad (_("Invalid register for post/pre increment."));
1804 break;
1807 f = frag_more (1);
1808 number_to_chars_bigendian (f, byte, 1);
1809 return 1;
1812 if (mode & (M6812_OP_IDX | M6812_OP_D_IDX_2))
1814 switch (op->reg1)
1816 case REG_X:
1817 byte = 0;
1818 break;
1820 case REG_Y:
1821 byte = 1;
1822 break;
1824 case REG_SP:
1825 byte = 2;
1826 break;
1828 case REG_PC:
1829 byte = 3;
1830 break;
1832 default:
1833 as_bad (_("Invalid register."));
1834 break;
1836 if (op->exp.X_op == O_constant)
1838 if (!check_range (val, M6812_OP_IDX))
1840 as_bad (_("Offset out of 16-bit range: %ld."), val);
1843 if (move_insn && !(val >= -16 && val <= 15))
1845 as_bad (_("Offset out of 5-bit range for movw/movb insn: %ld."),
1846 val);
1847 return -1;
1850 if (val >= -16 && val <= 15 && !(mode & M6812_OP_D_IDX_2))
1852 byte = byte << 6;
1853 byte |= val & 0x1f;
1854 f = frag_more (1);
1855 number_to_chars_bigendian (f, byte, 1);
1856 return 1;
1858 else if (val >= -256 && val <= 255 && !(mode & M6812_OP_D_IDX_2))
1860 byte = byte << 3;
1861 byte |= 0xe0;
1862 if (val < 0)
1863 byte |= 0x1;
1864 f = frag_more (2);
1865 number_to_chars_bigendian (f, byte, 1);
1866 number_to_chars_bigendian (f + 1, val & 0x0FF, 1);
1867 return 2;
1869 else
1871 byte = byte << 3;
1872 if (mode & M6812_OP_D_IDX_2)
1873 byte |= 0xe3;
1874 else
1875 byte |= 0xe2;
1877 f = frag_more (3);
1878 number_to_chars_bigendian (f, byte, 1);
1879 number_to_chars_bigendian (f + 1, val & 0x0FFFF, 2);
1880 return 3;
1883 if (mode & M6812_OP_D_IDX_2)
1885 byte = (byte << 3) | 0xe3;
1886 f = frag_more (1);
1887 number_to_chars_bigendian (f, byte, 1);
1889 fixup16 (&op->exp, 0, 0);
1891 else if (op->reg1 != REG_PC)
1893 symbolS *sym;
1894 offsetT off;
1896 f = frag_more (1);
1897 number_to_chars_bigendian (f, byte, 1);
1898 sym = op->exp.X_add_symbol;
1899 off = op->exp.X_add_number;
1900 if (op->exp.X_op != O_symbol)
1902 sym = make_expr_symbol (&op->exp);
1903 off = 0;
1905 /* movb/movw cannot be relaxed. */
1906 if (move_insn)
1908 byte <<= 6;
1909 number_to_chars_bigendian (f, byte, 1);
1910 fix_new (frag_now, f - frag_now->fr_literal, 1,
1911 sym, off, 0, BFD_RELOC_M68HC12_5B);
1912 return 1;
1914 else
1916 number_to_chars_bigendian (f, byte, 1);
1917 frag_var (rs_machine_dependent, 2, 2,
1918 ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_UNDF),
1919 sym, off, f);
1922 else
1924 f = frag_more (1);
1925 /* movb/movw cannot be relaxed. */
1926 if (move_insn)
1928 byte <<= 6;
1929 number_to_chars_bigendian (f, byte, 1);
1930 fix_new (frag_now, f - frag_now->fr_literal, 1,
1931 op->exp.X_add_symbol, op->exp.X_add_number, 0, BFD_RELOC_M68HC12_5B);
1932 return 1;
1934 else
1936 number_to_chars_bigendian (f, byte, 1);
1937 frag_var (rs_machine_dependent, 2, 2,
1938 ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_UNDF),
1939 op->exp.X_add_symbol,
1940 op->exp.X_add_number, f);
1943 return 3;
1946 if (mode & (M6812_OP_REG | M6812_OP_D_IDX))
1948 if (mode & M6812_OP_D_IDX)
1950 if (op->reg1 != REG_D)
1951 as_bad (_("Expecting register D for indexed indirect mode."));
1952 if (move_insn)
1953 as_bad (_("Indexed indirect mode is not allowed for movb/movw."));
1955 byte = 0xE7;
1957 else
1959 switch (op->reg1)
1961 case REG_A:
1962 byte = 0xE4;
1963 break;
1965 case REG_B:
1966 byte = 0xE5;
1967 break;
1969 default:
1970 as_bad (_("Invalid accumulator register."));
1972 case REG_D:
1973 byte = 0xE6;
1974 break;
1977 switch (op->reg2)
1979 case REG_X:
1980 break;
1982 case REG_Y:
1983 byte |= (1 << 3);
1984 break;
1986 case REG_SP:
1987 byte |= (2 << 3);
1988 break;
1990 case REG_PC:
1991 byte |= (3 << 3);
1992 break;
1994 default:
1995 as_bad (_("Invalid indexed register."));
1996 break;
1998 f = frag_more (1);
1999 number_to_chars_bigendian (f, byte, 1);
2000 return 1;
2003 as_fatal (_("Addressing mode not implemented yet."));
2004 return 0;
2007 /* Assemble the 68HC12 register mode byte. */
2008 static int
2009 build_reg_mode (operand *op, int format)
2011 unsigned char byte;
2012 char *f;
2014 if (format & M6812_OP_SEX_MARKER
2015 && op->reg1 != REG_A && op->reg1 != REG_B && op->reg1 != REG_CCR)
2016 as_bad (_("Invalid source register for this instruction, use 'tfr'."));
2017 else if (op->reg1 == REG_NONE || op->reg1 == REG_PC)
2018 as_bad (_("Invalid source register."));
2020 if (format & M6812_OP_SEX_MARKER
2021 && op->reg2 != REG_D
2022 && op->reg2 != REG_X && op->reg2 != REG_Y && op->reg2 != REG_SP)
2023 as_bad (_("Invalid destination register for this instruction, use 'tfr'."));
2024 else if (op->reg2 == REG_NONE || op->reg2 == REG_PC)
2025 as_bad (_("Invalid destination register."));
2027 byte = (op->reg1 << 4) | (op->reg2);
2028 if (format & M6812_OP_EXG_MARKER)
2029 byte |= 0x80;
2031 f = frag_more (1);
2032 number_to_chars_bigendian (f, byte, 1);
2033 return 1;
2036 /* build_insn takes a pointer to the opcode entry in the opcode table,
2037 the array of operand expressions and builds the corresponding instruction.
2038 This operation only deals with non relative jumps insn (need special
2039 handling). */
2040 static void
2041 build_insn (struct m68hc11_opcode *opcode, operand operands[],
2042 int nb_operands ATTRIBUTE_UNUSED)
2044 int i;
2045 char *f;
2046 long format;
2047 int move_insn = 0;
2049 /* Put the page code instruction if there is one. */
2050 format = opcode->format;
2052 if (format & M6811_OP_BRANCH)
2053 fix_new (frag_now, frag_now_fix (), 0,
2054 &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
2056 if (format & OP_EXTENDED)
2058 int page_code;
2060 f = m68hc11_new_insn (2);
2061 if (format & M6811_OP_PAGE2)
2062 page_code = M6811_OPCODE_PAGE2;
2063 else if (format & M6811_OP_PAGE3)
2064 page_code = M6811_OPCODE_PAGE3;
2065 else
2066 page_code = M6811_OPCODE_PAGE4;
2068 number_to_chars_bigendian (f, page_code, 1);
2069 f++;
2071 else
2072 f = m68hc11_new_insn (1);
2074 number_to_chars_bigendian (f, opcode->opcode, 1);
2076 i = 0;
2078 /* The 68HC12 movb and movw instructions are special. We have to handle
2079 them in a special way. */
2080 if (format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2))
2082 move_insn = 1;
2083 if (format & M6812_OP_IDX)
2085 build_indexed_byte (&operands[0], format, 1);
2086 i = 1;
2087 format &= ~M6812_OP_IDX;
2089 if (format & M6812_OP_IDX_P2)
2091 build_indexed_byte (&operands[1], format, 1);
2092 i = 0;
2093 format &= ~M6812_OP_IDX_P2;
2097 if (format & (M6811_OP_DIRECT | M6811_OP_IMM8))
2099 fixup8 (&operands[i].exp,
2100 format & (M6811_OP_DIRECT | M6811_OP_IMM8 | M6812_OP_TRAP_ID),
2101 operands[i].mode);
2102 i++;
2104 else if (IS_CALL_SYMBOL (format) && nb_operands == 1)
2106 format &= ~M6812_OP_PAGE;
2107 fixup24 (&operands[i].exp, format & M6811_OP_IND16,
2108 operands[i].mode);
2109 i++;
2111 else if (format & (M6811_OP_IMM16 | M6811_OP_IND16))
2113 fixup16 (&operands[i].exp,
2114 format & (M6811_OP_IMM16 | M6811_OP_IND16 | M6812_OP_PAGE),
2115 operands[i].mode);
2116 i++;
2118 else if (format & (M6811_OP_IX | M6811_OP_IY))
2120 if ((format & M6811_OP_IX) && (operands[0].reg1 != REG_X))
2121 as_bad (_("Invalid indexed register, expecting register X."));
2122 if ((format & M6811_OP_IY) && (operands[0].reg1 != REG_Y))
2123 as_bad (_("Invalid indexed register, expecting register Y."));
2125 fixup8 (&operands[0].exp, M6811_OP_IX, operands[0].mode);
2126 i = 1;
2128 else if (format &
2129 (M6812_OP_IDX | M6812_OP_IDX_2 | M6812_OP_IDX_1
2130 | M6812_OP_D_IDX | M6812_OP_D_IDX_2))
2132 build_indexed_byte (&operands[i], format, move_insn);
2133 i++;
2135 else if (format & M6812_OP_REG && current_architecture & cpu6812)
2137 build_reg_mode (&operands[i], format);
2138 i++;
2140 if (format & M6811_OP_BITMASK)
2142 fixup8 (&operands[i].exp, M6811_OP_BITMASK, operands[i].mode);
2143 i++;
2145 if (format & M6811_OP_JUMP_REL)
2147 fixup8 (&operands[i].exp, M6811_OP_JUMP_REL, operands[i].mode);
2149 else if (format & M6812_OP_IND16_P2)
2151 fixup16 (&operands[1].exp, M6811_OP_IND16, operands[1].mode);
2153 if (format & M6812_OP_PAGE)
2155 fixup8 (&operands[i].exp, M6812_OP_PAGE, operands[i].mode);
2159 /* Opcode identification and operand analysis. */
2161 /* find() gets a pointer to an entry in the opcode table. It must look at all
2162 opcodes with the same name and use the operands to choose the correct
2163 opcode. Returns the opcode pointer if there was a match and 0 if none. */
2164 static struct m68hc11_opcode *
2165 find (struct m68hc11_opcode_def *opc, operand operands[], int nb_operands)
2167 int i, match, pos;
2168 struct m68hc11_opcode *opcode;
2169 struct m68hc11_opcode *op_indirect;
2171 op_indirect = 0;
2172 opcode = opc->opcode;
2174 /* Now search the opcode table table for one with operands
2175 that matches what we've got. We're only done if the operands matched so
2176 far AND there are no more to check. */
2177 for (pos = match = 0; match == 0 && pos < opc->nb_modes; pos++, opcode++)
2179 int poss_indirect = 0;
2180 long format = opcode->format;
2181 int expect;
2183 expect = 0;
2184 if (opcode->format & M6811_OP_MASK)
2185 expect++;
2186 if (opcode->format & M6811_OP_BITMASK)
2187 expect++;
2188 if (opcode->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
2189 expect++;
2190 if (opcode->format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2))
2191 expect++;
2192 if ((opcode->format & M6812_OP_PAGE)
2193 && (!IS_CALL_SYMBOL (opcode->format) || nb_operands == 2))
2194 expect++;
2196 for (i = 0; expect == nb_operands && i < nb_operands; i++)
2198 int mode = operands[i].mode;
2200 if (mode & M6811_OP_IMM16)
2202 if (format &
2203 (M6811_OP_IMM8 | M6811_OP_IMM16 | M6811_OP_BITMASK))
2204 continue;
2205 break;
2207 if (mode == M6811_OP_DIRECT)
2209 if (format & M6811_OP_DIRECT)
2210 continue;
2212 /* If the operand is a page 0 operand, remember a
2213 possible <abs-16> addressing mode. We mark
2214 this and continue to check other operands. */
2215 if (format & M6811_OP_IND16
2216 && flag_strict_direct_addressing && op_indirect == 0)
2218 poss_indirect = 1;
2219 continue;
2221 break;
2223 if (mode & M6811_OP_IND16)
2225 if (i == 0 && (format & M6811_OP_IND16) != 0)
2226 continue;
2227 if (i != 0 && (format & M6812_OP_PAGE) != 0)
2228 continue;
2229 if (i != 0 && (format & M6812_OP_IND16_P2) != 0)
2230 continue;
2231 if (i == 0 && (format & M6811_OP_BITMASK))
2232 break;
2234 if (mode & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
2236 if (format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
2237 continue;
2239 if (mode & M6812_OP_REG)
2241 if (i == 0
2242 && (format & M6812_OP_REG)
2243 && (operands[i].reg2 == REG_NONE))
2244 continue;
2245 if (i == 0
2246 && (format & M6812_OP_REG)
2247 && (format & M6812_OP_REG_2)
2248 && (operands[i].reg2 != REG_NONE))
2249 continue;
2250 if (i == 0
2251 && (format & M6812_OP_IDX)
2252 && (operands[i].reg2 != REG_NONE))
2253 continue;
2254 if (i == 0
2255 && (format & M6812_OP_IDX)
2256 && (format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2)))
2257 continue;
2258 if (i == 1
2259 && (format & M6812_OP_IDX_P2))
2260 continue;
2261 break;
2263 if (mode & M6812_OP_IDX)
2265 if (format & M6811_OP_IX && operands[i].reg1 == REG_X)
2266 continue;
2267 if (format & M6811_OP_IY && operands[i].reg1 == REG_Y)
2268 continue;
2269 if (i == 0
2270 && format & (M6812_OP_IDX | M6812_OP_IDX_1 | M6812_OP_IDX_2)
2271 && (operands[i].reg1 == REG_X
2272 || operands[i].reg1 == REG_Y
2273 || operands[i].reg1 == REG_SP
2274 || operands[i].reg1 == REG_PC))
2275 continue;
2276 if (i == 1 && format & M6812_OP_IDX_P2)
2277 continue;
2279 if (mode & format & (M6812_OP_D_IDX | M6812_OP_D_IDX_2))
2281 if (i == 0)
2282 continue;
2284 if (mode & M6812_AUTO_INC_DEC)
2286 if (i == 0
2287 && format & (M6812_OP_IDX | M6812_OP_IDX_1 |
2288 M6812_OP_IDX_2))
2289 continue;
2290 if (i == 1 && format & M6812_OP_IDX_P2)
2291 continue;
2293 break;
2295 match = i == nb_operands;
2297 /* Operands are ok but an operand uses page 0 addressing mode
2298 while the insn supports abs-16 mode. Keep a reference to this
2299 insns in case there is no insn supporting page 0 addressing. */
2300 if (match && poss_indirect)
2302 op_indirect = opcode;
2303 match = 0;
2305 if (match)
2306 break;
2309 /* Page 0 addressing is used but not supported by any insn.
2310 If absolute addresses are supported, we use that insn. */
2311 if (match == 0 && op_indirect)
2313 opcode = op_indirect;
2314 match = 1;
2317 if (!match)
2319 return (0);
2322 return opcode;
2325 /* Find the real opcode and its associated operands. We use a progressive
2326 approach here. On entry, 'opc' points to the first opcode in the
2327 table that matches the opcode name in the source line. We try to
2328 isolate an operand, find a possible match in the opcode table.
2329 We isolate another operand if no match were found. The table 'operands'
2330 is filled while operands are recognized.
2332 Returns the opcode pointer that matches the opcode name in the
2333 source line and the associated operands. */
2334 static struct m68hc11_opcode *
2335 find_opcode (struct m68hc11_opcode_def *opc, operand operands[],
2336 int *nb_operands)
2338 struct m68hc11_opcode *opcode;
2339 int i;
2341 if (opc->max_operands == 0)
2343 *nb_operands = 0;
2344 return opc->opcode;
2347 for (i = 0; i < opc->max_operands;)
2349 int result;
2351 result = get_operand (&operands[i], i, opc->format);
2352 if (result <= 0)
2353 return 0;
2355 /* Special case where the bitmask of the bclr/brclr
2356 instructions is not introduced by #.
2357 Example: bclr 3,x $80. */
2358 if (i == 1 && (opc->format & M6811_OP_BITMASK)
2359 && (operands[i].mode & M6811_OP_IND16))
2361 operands[i].mode = M6811_OP_IMM16;
2364 i += result;
2365 *nb_operands = i;
2366 if (i >= opc->min_operands)
2368 opcode = find (opc, operands, i);
2370 /* Another special case for 'call foo,page' instructions.
2371 Since we support 'call foo' and 'call foo,page' we must look
2372 if the optional page specification is present otherwise we will
2373 assemble immediately and treat the page spec as garbage. */
2374 if (opcode && !(opcode->format & M6812_OP_PAGE))
2375 return opcode;
2377 if (opcode && *input_line_pointer != ',')
2378 return opcode;
2381 if (*input_line_pointer == ',')
2382 input_line_pointer++;
2385 return 0;
2388 #define M6812_XBCC_MARKER (M6812_OP_TBCC_MARKER \
2389 | M6812_OP_DBCC_MARKER \
2390 | M6812_OP_IBCC_MARKER)
2392 /* Gas line assembler entry point. */
2394 /* This is the main entry point for the machine-dependent assembler. str
2395 points to a machine-dependent instruction. This function is supposed to
2396 emit the frags/bytes it assembles to. */
2397 void
2398 md_assemble (char *str)
2400 struct m68hc11_opcode_def *opc;
2401 struct m68hc11_opcode *opcode;
2403 unsigned char *op_start, *op_end;
2404 char *save;
2405 char name[20];
2406 int nlen = 0;
2407 operand operands[M6811_MAX_OPERANDS];
2408 int nb_operands = 0;
2409 int branch_optimize = 0;
2410 int alias_id = -1;
2412 /* Drop leading whitespace. */
2413 while (*str == ' ')
2414 str++;
2416 /* Find the opcode end and get the opcode in 'name'. The opcode is forced
2417 lower case (the opcode table only has lower case op-codes). */
2418 for (op_start = op_end = (unsigned char *) str;
2419 *op_end && nlen < 20 && !is_end_of_line[*op_end] && *op_end != ' ';
2420 op_end++)
2422 name[nlen] = TOLOWER (op_start[nlen]);
2423 nlen++;
2425 name[nlen] = 0;
2427 if (nlen == 0)
2429 as_bad (_("No instruction or missing opcode."));
2430 return;
2433 /* Find the opcode definition given its name. */
2434 opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash, name);
2436 /* If it's not recognized, look for 'jbsr' and 'jbxx'. These are
2437 pseudo insns for relative branch. For these branches, we always
2438 optimize them (turned into absolute branches) even if --short-branches
2439 is given. */
2440 if (opc == NULL && name[0] == 'j' && name[1] == 'b')
2442 opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash, &name[1]);
2443 if (opc
2444 && (!(opc->format & M6811_OP_JUMP_REL)
2445 || (opc->format & M6811_OP_BITMASK)))
2446 opc = 0;
2447 if (opc)
2448 branch_optimize = 1;
2451 /* The following test should probably be removed. This is not conform
2452 to Motorola assembler specs. */
2453 if (opc == NULL && flag_mri)
2455 if (*op_end == ' ' || *op_end == '\t')
2457 while (*op_end == ' ' || *op_end == '\t')
2458 op_end++;
2460 if (nlen < 19
2461 && (*op_end &&
2462 (is_end_of_line[op_end[1]]
2463 || op_end[1] == ' ' || op_end[1] == '\t'
2464 || !ISALNUM (op_end[1])))
2465 && (*op_end == 'a' || *op_end == 'b'
2466 || *op_end == 'A' || *op_end == 'B'
2467 || *op_end == 'd' || *op_end == 'D'
2468 || *op_end == 'x' || *op_end == 'X'
2469 || *op_end == 'y' || *op_end == 'Y'))
2471 name[nlen++] = TOLOWER (*op_end++);
2472 name[nlen] = 0;
2473 opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash,
2474 name);
2479 /* Identify a possible instruction alias. There are some on the
2480 68HC12 to emulate a few 68HC11 instructions. */
2481 if (opc == NULL && (current_architecture & cpu6812))
2483 int i;
2485 for (i = 0; i < m68hc12_num_alias; i++)
2486 if (strcmp (m68hc12_alias[i].name, name) == 0)
2488 alias_id = i;
2489 break;
2492 if (opc == NULL && alias_id < 0)
2494 as_bad (_("Opcode `%s' is not recognized."), name);
2495 return;
2497 save = input_line_pointer;
2498 input_line_pointer = (char *) op_end;
2500 if (opc)
2502 opc->used++;
2503 opcode = find_opcode (opc, operands, &nb_operands);
2505 else
2506 opcode = 0;
2508 if ((opcode || alias_id >= 0) && !flag_mri)
2510 char *p = input_line_pointer;
2512 while (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r')
2513 p++;
2515 if (*p != '\n' && *p)
2516 as_bad (_("Garbage at end of instruction: `%s'."), p);
2519 input_line_pointer = save;
2521 if (alias_id >= 0)
2523 char *f = m68hc11_new_insn (m68hc12_alias[alias_id].size);
2525 number_to_chars_bigendian (f, m68hc12_alias[alias_id].code1, 1);
2526 if (m68hc12_alias[alias_id].size > 1)
2527 number_to_chars_bigendian (f + 1, m68hc12_alias[alias_id].code2, 1);
2529 return;
2532 /* Opcode is known but does not have valid operands. Print out the
2533 syntax for this opcode. */
2534 if (opcode == 0)
2536 if (flag_print_insn_syntax)
2537 print_insn_format (name);
2539 as_bad (_("Invalid operand for `%s'"), name);
2540 return;
2543 /* Treat dbeq/ibeq/tbeq instructions in a special way. The branch is
2544 relative and must be in the range -256..255 (9-bits). */
2545 if ((opcode->format & M6812_XBCC_MARKER)
2546 && (opcode->format & M6811_OP_JUMP_REL))
2547 build_dbranch_insn (opcode, operands, nb_operands, branch_optimize);
2549 /* Relative jumps instructions are taken care of separately. We have to make
2550 sure that the relative branch is within the range -128..127. If it's out
2551 of range, the instructions are changed into absolute instructions.
2552 This is not supported for the brset and brclr instructions. */
2553 else if ((opcode->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
2554 && !(opcode->format & M6811_OP_BITMASK))
2555 build_jump_insn (opcode, operands, nb_operands, branch_optimize);
2556 else
2557 build_insn (opcode, operands, nb_operands);
2561 /* Pseudo op to control the ELF flags. */
2562 static void
2563 s_m68hc11_mode (int x ATTRIBUTE_UNUSED)
2565 char *name = input_line_pointer, ch;
2567 while (!is_end_of_line[(unsigned char) *input_line_pointer])
2568 input_line_pointer++;
2569 ch = *input_line_pointer;
2570 *input_line_pointer = '\0';
2572 if (strcmp (name, "mshort") == 0)
2574 elf_flags &= ~E_M68HC11_I32;
2576 else if (strcmp (name, "mlong") == 0)
2578 elf_flags |= E_M68HC11_I32;
2580 else if (strcmp (name, "mshort-double") == 0)
2582 elf_flags &= ~E_M68HC11_F64;
2584 else if (strcmp (name, "mlong-double") == 0)
2586 elf_flags |= E_M68HC11_F64;
2588 else
2590 as_warn (_("Invalid mode: %s\n"), name);
2592 *input_line_pointer = ch;
2593 demand_empty_rest_of_line ();
2596 /* Mark the symbols with STO_M68HC12_FAR to indicate the functions
2597 are using 'rtc' for returning. It is necessary to use 'call'
2598 to invoke them. This is also used by the debugger to correctly
2599 find the stack frame. */
2600 static void
2601 s_m68hc11_mark_symbol (int mark)
2603 char *name;
2604 int c;
2605 symbolS *symbolP;
2606 asymbol *bfdsym;
2607 elf_symbol_type *elfsym;
2611 name = input_line_pointer;
2612 c = get_symbol_end ();
2613 symbolP = symbol_find_or_make (name);
2614 *input_line_pointer = c;
2616 SKIP_WHITESPACE ();
2618 bfdsym = symbol_get_bfdsym (symbolP);
2619 elfsym = elf_symbol_from (bfd_asymbol_bfd (bfdsym), bfdsym);
2621 assert (elfsym);
2623 /* Mark the symbol far (using rtc for function return). */
2624 elfsym->internal_elf_sym.st_other |= mark;
2626 if (c == ',')
2628 input_line_pointer ++;
2630 SKIP_WHITESPACE ();
2632 if (*input_line_pointer == '\n')
2633 c = '\n';
2636 while (c == ',');
2638 demand_empty_rest_of_line ();
2641 static void
2642 s_m68hc11_relax (int ignore ATTRIBUTE_UNUSED)
2644 expressionS ex;
2646 expression (&ex);
2648 if (ex.X_op != O_symbol || ex.X_add_number != 0)
2650 as_bad (_("bad .relax format"));
2651 ignore_rest_of_line ();
2652 return;
2655 fix_new_exp (frag_now, frag_now_fix (), 0, &ex, 1,
2656 BFD_RELOC_M68HC11_RL_GROUP);
2658 demand_empty_rest_of_line ();
2662 /* Relocation, relaxation and frag conversions. */
2664 /* PC-relative offsets are relative to the start of the
2665 next instruction. That is, the address of the offset, plus its
2666 size, since the offset is always the last part of the insn. */
2667 long
2668 md_pcrel_from (fixS *fixP)
2670 if (fixP->fx_r_type == BFD_RELOC_M68HC11_RL_JUMP)
2671 return 0;
2673 return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
2676 /* If while processing a fixup, a reloc really needs to be created
2677 then it is done here. */
2678 arelent *
2679 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
2681 arelent *reloc;
2683 reloc = (arelent *) xmalloc (sizeof (arelent));
2684 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
2685 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
2686 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
2687 if (fixp->fx_r_type == 0)
2688 reloc->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_16);
2689 else
2690 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
2691 if (reloc->howto == (reloc_howto_type *) NULL)
2693 as_bad_where (fixp->fx_file, fixp->fx_line,
2694 _("Relocation %d is not supported by object file format."),
2695 (int) fixp->fx_r_type);
2696 return NULL;
2699 /* Since we use Rel instead of Rela, encode the vtable entry to be
2700 used in the relocation's section offset. */
2701 if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
2702 reloc->address = fixp->fx_offset;
2704 reloc->addend = 0;
2705 return reloc;
2708 /* We need a port-specific relaxation function to cope with sym2 - sym1
2709 relative expressions with both symbols in the same segment (but not
2710 necessarily in the same frag as this insn), for example:
2711 ldab sym2-(sym1-2),pc
2712 sym1:
2713 The offset can be 5, 9 or 16 bits long. */
2715 long
2716 m68hc11_relax_frag (segT seg ATTRIBUTE_UNUSED, fragS *fragP,
2717 long stretch ATTRIBUTE_UNUSED)
2719 long growth;
2720 offsetT aim = 0;
2721 symbolS *symbolP;
2722 const relax_typeS *this_type;
2723 const relax_typeS *start_type;
2724 relax_substateT next_state;
2725 relax_substateT this_state;
2726 const relax_typeS *table = TC_GENERIC_RELAX_TABLE;
2728 /* We only have to cope with frags as prepared by
2729 md_estimate_size_before_relax. The STATE_BITS16 case may geet here
2730 because of the different reasons that it's not relaxable. */
2731 switch (fragP->fr_subtype)
2733 case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS16):
2734 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16):
2735 /* When we get to this state, the frag won't grow any more. */
2736 return 0;
2738 case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS5):
2739 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS5):
2740 case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS9):
2741 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9):
2742 if (fragP->fr_symbol == NULL
2743 || S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
2744 as_fatal (_("internal inconsistency problem in %s: fr_symbol %lx"),
2745 __FUNCTION__, (long) fragP->fr_symbol);
2746 symbolP = fragP->fr_symbol;
2747 if (symbol_resolved_p (symbolP))
2748 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
2749 __FUNCTION__);
2750 aim = S_GET_VALUE (symbolP);
2751 break;
2753 default:
2754 as_fatal (_("internal inconsistency problem in %s: fr_subtype %d"),
2755 __FUNCTION__, fragP->fr_subtype);
2758 /* The rest is stolen from relax_frag. There's no obvious way to
2759 share the code, but fortunately no requirement to keep in sync as
2760 long as fragP->fr_symbol does not have its segment changed. */
2762 this_state = fragP->fr_subtype;
2763 start_type = this_type = table + this_state;
2765 if (aim < 0)
2767 /* Look backwards. */
2768 for (next_state = this_type->rlx_more; next_state;)
2769 if (aim >= this_type->rlx_backward)
2770 next_state = 0;
2771 else
2773 /* Grow to next state. */
2774 this_state = next_state;
2775 this_type = table + this_state;
2776 next_state = this_type->rlx_more;
2779 else
2781 /* Look forwards. */
2782 for (next_state = this_type->rlx_more; next_state;)
2783 if (aim <= this_type->rlx_forward)
2784 next_state = 0;
2785 else
2787 /* Grow to next state. */
2788 this_state = next_state;
2789 this_type = table + this_state;
2790 next_state = this_type->rlx_more;
2794 growth = this_type->rlx_length - start_type->rlx_length;
2795 if (growth != 0)
2796 fragP->fr_subtype = this_state;
2797 return growth;
2800 void
2801 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, asection *sec ATTRIBUTE_UNUSED,
2802 fragS *fragP)
2804 fixS *fixp;
2805 long value;
2806 long disp;
2807 char *buffer_address = fragP->fr_literal;
2809 /* Address in object code of the displacement. */
2810 register int object_address = fragP->fr_fix + fragP->fr_address;
2812 buffer_address += fragP->fr_fix;
2814 /* The displacement of the address, from current location. */
2815 value = S_GET_VALUE (fragP->fr_symbol);
2816 disp = (value + fragP->fr_offset) - object_address;
2818 switch (fragP->fr_subtype)
2820 case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE):
2821 fragP->fr_opcode[1] = disp;
2822 break;
2824 case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD):
2825 /* This relax is only for bsr and bra. */
2826 assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
2827 || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
2828 || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
2830 fragP->fr_opcode[0] = convert_branch (fragP->fr_opcode[0]);
2832 fix_new (fragP, fragP->fr_fix - 1, 2,
2833 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
2834 fragP->fr_fix += 1;
2835 break;
2837 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_BYTE):
2838 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_BYTE):
2839 fragP->fr_opcode[1] = disp;
2840 break;
2842 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_WORD):
2843 /* Invert branch. */
2844 fragP->fr_opcode[0] ^= 1;
2845 fragP->fr_opcode[1] = 3; /* Branch offset. */
2846 buffer_address[0] = M6811_JMP;
2847 fix_new (fragP, fragP->fr_fix + 1, 2,
2848 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
2849 fragP->fr_fix += 3;
2850 break;
2852 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_WORD):
2853 /* Translate branch into a long branch. */
2854 fragP->fr_opcode[1] = fragP->fr_opcode[0];
2855 fragP->fr_opcode[0] = M6811_OPCODE_PAGE2;
2857 fixp = fix_new (fragP, fragP->fr_fix, 2,
2858 fragP->fr_symbol, fragP->fr_offset, 1,
2859 BFD_RELOC_16_PCREL);
2860 fixp->fx_pcrel_adjust = 2;
2861 fragP->fr_fix += 2;
2862 break;
2864 case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS5):
2865 if (fragP->fr_symbol != 0
2866 && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
2867 value = disp;
2868 /* fall through */
2870 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS5):
2871 fragP->fr_opcode[0] = fragP->fr_opcode[0] << 6;
2872 fragP->fr_opcode[0] |= value & 0x1f;
2873 break;
2875 case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS9):
2876 /* For a PC-relative offset, use the displacement with a -1 correction
2877 to take into account the additional byte of the insn. */
2878 if (fragP->fr_symbol != 0
2879 && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
2880 value = disp - 1;
2881 /* fall through */
2883 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9):
2884 fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3);
2885 fragP->fr_opcode[0] |= 0xE0;
2886 fragP->fr_opcode[0] |= (value >> 8) & 1;
2887 fragP->fr_opcode[1] = value;
2888 fragP->fr_fix += 1;
2889 break;
2891 case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS16):
2892 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16):
2893 fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3);
2894 fragP->fr_opcode[0] |= 0xe2;
2895 if ((fragP->fr_opcode[0] & 0x0ff) == 0x0fa
2896 && fragP->fr_symbol != 0
2897 && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
2899 fixp = fix_new (fragP, fragP->fr_fix, 2,
2900 fragP->fr_symbol, fragP->fr_offset,
2901 1, BFD_RELOC_16_PCREL);
2903 else
2905 fix_new (fragP, fragP->fr_fix, 2,
2906 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
2908 fragP->fr_fix += 2;
2909 break;
2911 case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_BYTE):
2912 if (disp < 0)
2913 fragP->fr_opcode[0] |= 0x10;
2915 fragP->fr_opcode[1] = disp & 0x0FF;
2916 break;
2918 case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_WORD):
2919 /* Invert branch. */
2920 fragP->fr_opcode[0] ^= 0x20;
2921 fragP->fr_opcode[1] = 3; /* Branch offset. */
2922 buffer_address[0] = M6812_JMP;
2923 fix_new (fragP, fragP->fr_fix + 1, 2,
2924 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
2925 fragP->fr_fix += 3;
2926 break;
2928 default:
2929 break;
2933 /* On an ELF system, we can't relax a weak symbol. The weak symbol
2934 can be overridden at final link time by a non weak symbol. We can
2935 relax externally visible symbol because there is no shared library
2936 and such symbol can't be overridden (unless they are weak). */
2937 static int
2938 relaxable_symbol (symbolS *symbol)
2940 return ! S_IS_WEAK (symbol);
2943 /* Force truly undefined symbols to their maximum size, and generally set up
2944 the frag list to be relaxed. */
2946 md_estimate_size_before_relax (fragS *fragP, asection *segment)
2948 if (RELAX_LENGTH (fragP->fr_subtype) == STATE_UNDF)
2950 if (S_GET_SEGMENT (fragP->fr_symbol) != segment
2951 || !relaxable_symbol (fragP->fr_symbol)
2952 || (segment != absolute_section
2953 && RELAX_STATE (fragP->fr_subtype) == STATE_INDEXED_OFFSET))
2955 /* Non-relaxable cases. */
2956 int old_fr_fix;
2957 char *buffer_address;
2959 old_fr_fix = fragP->fr_fix;
2960 buffer_address = fragP->fr_fix + fragP->fr_literal;
2962 switch (RELAX_STATE (fragP->fr_subtype))
2964 case STATE_PC_RELATIVE:
2966 /* This relax is only for bsr and bra. */
2967 assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
2968 || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
2969 || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
2971 if (flag_fixed_branches)
2972 as_bad_where (fragP->fr_file, fragP->fr_line,
2973 _("bra or bsr with undefined symbol."));
2975 /* The symbol is undefined or in a separate section.
2976 Turn bra into a jmp and bsr into a jsr. The insn
2977 becomes 3 bytes long (instead of 2). A fixup is
2978 necessary for the unresolved symbol address. */
2979 fragP->fr_opcode[0] = convert_branch (fragP->fr_opcode[0]);
2981 fix_new (fragP, fragP->fr_fix - 1, 2, fragP->fr_symbol,
2982 fragP->fr_offset, 0, BFD_RELOC_16);
2983 fragP->fr_fix++;
2984 break;
2986 case STATE_CONDITIONAL_BRANCH:
2987 assert (current_architecture & cpu6811);
2989 fragP->fr_opcode[0] ^= 1; /* Reverse sense of branch. */
2990 fragP->fr_opcode[1] = 3; /* Skip next jmp insn (3 bytes). */
2992 /* Don't use fr_opcode[2] because this may be
2993 in a different frag. */
2994 buffer_address[0] = M6811_JMP;
2996 fragP->fr_fix++;
2997 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
2998 fragP->fr_offset, 0, BFD_RELOC_16);
2999 fragP->fr_fix += 2;
3000 break;
3002 case STATE_INDEXED_OFFSET:
3003 assert (current_architecture & cpu6812);
3005 if (fragP->fr_symbol
3006 && S_GET_SEGMENT (fragP->fr_symbol) == absolute_section)
3008 fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_OFFSET,
3009 STATE_BITS5);
3010 /* Return the size of the variable part of the frag. */
3011 return md_relax_table[fragP->fr_subtype].rlx_length;
3013 else
3015 /* Switch the indexed operation to 16-bit mode. */
3016 fragP->fr_opcode[0] = fragP->fr_opcode[0] << 3;
3017 fragP->fr_opcode[0] |= 0xe2;
3018 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
3019 fragP->fr_offset, 0, BFD_RELOC_16);
3020 fragP->fr_fix += 2;
3022 break;
3024 case STATE_INDEXED_PCREL:
3025 assert (current_architecture & cpu6812);
3027 if (fragP->fr_symbol
3028 && S_GET_SEGMENT (fragP->fr_symbol) == absolute_section)
3030 fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_PCREL,
3031 STATE_BITS5);
3032 /* Return the size of the variable part of the frag. */
3033 return md_relax_table[fragP->fr_subtype].rlx_length;
3035 else
3037 fixS* fixp;
3039 fragP->fr_opcode[0] = fragP->fr_opcode[0] << 3;
3040 fragP->fr_opcode[0] |= 0xe2;
3041 fixp = fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
3042 fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
3043 fragP->fr_fix += 2;
3045 break;
3047 case STATE_XBCC_BRANCH:
3048 assert (current_architecture & cpu6812);
3050 fragP->fr_opcode[0] ^= 0x20; /* Reverse sense of branch. */
3051 fragP->fr_opcode[1] = 3; /* Skip next jmp insn (3 bytes). */
3053 /* Don't use fr_opcode[2] because this may be
3054 in a different frag. */
3055 buffer_address[0] = M6812_JMP;
3057 fragP->fr_fix++;
3058 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
3059 fragP->fr_offset, 0, BFD_RELOC_16);
3060 fragP->fr_fix += 2;
3061 break;
3063 case STATE_CONDITIONAL_BRANCH_6812:
3064 assert (current_architecture & cpu6812);
3066 /* Translate into a lbcc branch. */
3067 fragP->fr_opcode[1] = fragP->fr_opcode[0];
3068 fragP->fr_opcode[0] = M6811_OPCODE_PAGE2;
3070 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
3071 fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
3072 fragP->fr_fix += 2;
3073 break;
3075 default:
3076 as_fatal (_("Subtype %d is not recognized."), fragP->fr_subtype);
3078 frag_wane (fragP);
3080 /* Return the growth in the fixed part of the frag. */
3081 return fragP->fr_fix - old_fr_fix;
3084 /* Relaxable cases. */
3085 switch (RELAX_STATE (fragP->fr_subtype))
3087 case STATE_PC_RELATIVE:
3088 /* This relax is only for bsr and bra. */
3089 assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
3090 || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
3091 || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
3093 fragP->fr_subtype = ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE);
3094 break;
3096 case STATE_CONDITIONAL_BRANCH:
3097 assert (current_architecture & cpu6811);
3099 fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH,
3100 STATE_BYTE);
3101 break;
3103 case STATE_INDEXED_OFFSET:
3104 assert (current_architecture & cpu6812);
3106 fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_OFFSET,
3107 STATE_BITS5);
3108 break;
3110 case STATE_INDEXED_PCREL:
3111 assert (current_architecture & cpu6812);
3113 fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_PCREL,
3114 STATE_BITS5);
3115 break;
3117 case STATE_XBCC_BRANCH:
3118 assert (current_architecture & cpu6812);
3120 fragP->fr_subtype = ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_BYTE);
3121 break;
3123 case STATE_CONDITIONAL_BRANCH_6812:
3124 assert (current_architecture & cpu6812);
3126 fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812,
3127 STATE_BYTE);
3128 break;
3132 if (fragP->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))
3133 as_fatal (_("Subtype %d is not recognized."), fragP->fr_subtype);
3135 /* Return the size of the variable part of the frag. */
3136 return md_relax_table[fragP->fr_subtype].rlx_length;
3139 /* See whether we need to force a relocation into the output file. */
3141 tc_m68hc11_force_relocation (fixS *fixP)
3143 if (fixP->fx_r_type == BFD_RELOC_M68HC11_RL_GROUP)
3144 return 1;
3146 return generic_force_reloc (fixP);
3149 /* Here we decide which fixups can be adjusted to make them relative
3150 to the beginning of the section instead of the symbol. Basically
3151 we need to make sure that the linker relaxation is done
3152 correctly, so in some cases we force the original symbol to be
3153 used. */
3155 tc_m68hc11_fix_adjustable (fixS *fixP)
3157 switch (fixP->fx_r_type)
3159 /* For the linker relaxation to work correctly, these relocs
3160 need to be on the symbol itself. */
3161 case BFD_RELOC_16:
3162 case BFD_RELOC_M68HC11_RL_JUMP:
3163 case BFD_RELOC_M68HC11_RL_GROUP:
3164 case BFD_RELOC_VTABLE_INHERIT:
3165 case BFD_RELOC_VTABLE_ENTRY:
3166 case BFD_RELOC_32:
3168 /* The memory bank addressing translation also needs the original
3169 symbol. */
3170 case BFD_RELOC_M68HC11_LO16:
3171 case BFD_RELOC_M68HC11_PAGE:
3172 case BFD_RELOC_M68HC11_24:
3173 return 0;
3175 default:
3176 return 1;
3180 void
3181 md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
3183 char *where;
3184 long value = * valP;
3185 int op_type;
3187 if (fixP->fx_addsy == (symbolS *) NULL)
3188 fixP->fx_done = 1;
3190 /* We don't actually support subtracting a symbol. */
3191 if (fixP->fx_subsy != (symbolS *) NULL)
3192 as_bad_where (fixP->fx_file, fixP->fx_line, _("Expression too complex."));
3194 op_type = fixP->fx_r_type;
3196 /* Patch the instruction with the resolved operand. Elf relocation
3197 info will also be generated to take care of linker/loader fixups.
3198 The 68HC11 addresses only 64Kb, we are only concerned by 8 and 16-bit
3199 relocs. BFD_RELOC_8 is basically used for .page0 access (the linker
3200 will warn for overflows). BFD_RELOC_8_PCREL should not be generated
3201 because it's either resolved or turned out into non-relative insns (see
3202 relax table, bcc, bra, bsr transformations)
3204 The BFD_RELOC_32 is necessary for the support of --gstabs. */
3205 where = fixP->fx_frag->fr_literal + fixP->fx_where;
3207 switch (fixP->fx_r_type)
3209 case BFD_RELOC_32:
3210 bfd_putb32 ((bfd_vma) value, (unsigned char *) where);
3211 break;
3213 case BFD_RELOC_24:
3214 case BFD_RELOC_M68HC11_24:
3215 bfd_putb16 ((bfd_vma) (value & 0x0ffff), (unsigned char *) where);
3216 ((bfd_byte*) where)[2] = ((value >> 16) & 0x0ff);
3217 break;
3219 case BFD_RELOC_16:
3220 case BFD_RELOC_16_PCREL:
3221 case BFD_RELOC_M68HC11_LO16:
3222 bfd_putb16 ((bfd_vma) value, (unsigned char *) where);
3223 if (value < -65537 || value > 65535)
3224 as_bad_where (fixP->fx_file, fixP->fx_line,
3225 _("Value out of 16-bit range."));
3226 break;
3228 case BFD_RELOC_M68HC11_HI8:
3229 value = value >> 8;
3230 /* Fall through. */
3232 case BFD_RELOC_M68HC11_LO8:
3233 case BFD_RELOC_8:
3234 case BFD_RELOC_M68HC11_PAGE:
3235 ((bfd_byte *) where)[0] = (bfd_byte) value;
3236 break;
3238 case BFD_RELOC_8_PCREL:
3239 ((bfd_byte *) where)[0] = (bfd_byte) value;
3241 if (value < -128 || value > 127)
3242 as_bad_where (fixP->fx_file, fixP->fx_line,
3243 _("Value %ld too large for 8-bit PC-relative branch."),
3244 value);
3245 break;
3247 case BFD_RELOC_M68HC11_3B:
3248 if (value <= 0 || value > 8)
3249 as_bad_where (fixP->fx_file, fixP->fx_line,
3250 _("Auto increment/decrement offset '%ld' is out of range."),
3251 value);
3252 if (where[0] & 0x8)
3253 value = 8 - value;
3254 else
3255 value--;
3257 where[0] = where[0] | (value & 0x07);
3258 break;
3260 case BFD_RELOC_M68HC12_5B:
3261 if (value < -16 || value > 15)
3262 as_bad_where (fixP->fx_file, fixP->fx_line,
3263 _("Offset out of 5-bit range for movw/movb insn: %ld"),
3264 value);
3265 if (value >= 0)
3266 where[0] |= value;
3267 else
3268 where[0] |= (0x10 | (16 + value));
3269 break;
3271 case BFD_RELOC_M68HC11_RL_JUMP:
3272 case BFD_RELOC_M68HC11_RL_GROUP:
3273 case BFD_RELOC_VTABLE_INHERIT:
3274 case BFD_RELOC_VTABLE_ENTRY:
3275 fixP->fx_done = 0;
3276 return;
3278 default:
3279 as_fatal (_("Line %d: unknown relocation type: 0x%x."),
3280 fixP->fx_line, fixP->fx_r_type);
3284 /* Set the ELF specific flags. */
3285 void
3286 m68hc11_elf_final_processing (void)
3288 if (current_architecture & cpu6812s)
3289 elf_flags |= EF_M68HCS12_MACH;
3290 elf_elfheader (stdoutput)->e_flags &= ~EF_M68HC11_ABI;
3291 elf_elfheader (stdoutput)->e_flags |= elf_flags;