The 2.41 release!
[binutils-gdb.git] / gas / config / tc-m68hc11.c
blob270ddf999ce10c482f6b8aa67167d01c285a0308
1 /* tc-m68hc11.c -- Assembler code for the Motorola 68HC11 & 68HC12.
2 Copyright (C) 1999-2023 Free Software Foundation, Inc.
3 Written by Stephane Carrez (stcarrez@nerim.fr)
4 XGATE and S12X added by James Murray (jsm@jsm-net.demon.co.uk)
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[] =
70 {1, 1, 0, 0}, /* First entries aren't used. */
71 {1, 1, 0, 0}, /* For no good reason except. */
72 {1, 1, 0, 0}, /* that the VAX doesn't either. */
73 {1, 1, 0, 0},
75 /* Relax for bcc <L>.
76 These insns are translated into b!cc +3 jmp L. */
77 {(127), (-128), 0, ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_WORD)},
78 {0, 0, 3, 0},
79 {1, 1, 0, 0},
80 {1, 1, 0, 0},
82 /* Relax for bsr <L> and bra <L>.
83 These insns are translated into jsr and jmp. */
84 {(127), (-128), 0, ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD)},
85 {0, 0, 1, 0},
86 {1, 1, 0, 0},
87 {1, 1, 0, 0},
89 /* Relax for indexed offset: 5-bits, 9-bits, 16-bits. */
90 {(15), (-16), 0, ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9)},
91 {(255), (-256), 1, ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16)},
92 {0, 0, 2, 0},
93 {1, 1, 0, 0},
95 /* Relax for PC relative offset: 5-bits, 9-bits, 16-bits.
96 For the 9-bit case, there will be a -1 correction to take into
97 account the new byte that's why the range is -255..256. */
98 {(15), (-16), 0, ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS9)},
99 {(256), (-255), 1, ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS16)},
100 {0, 0, 2, 0},
101 {1, 1, 0, 0},
103 /* Relax for dbeq/ibeq/tbeq r,<L>:
104 These insns are translated into db!cc +3 jmp L. */
105 {(255), (-256), 0, ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_WORD)},
106 {0, 0, 3, 0},
107 {1, 1, 0, 0},
108 {1, 1, 0, 0},
110 /* Relax for bcc <L> on 68HC12.
111 These insns are translated into lbcc <L>. */
112 {(127), (-128), 0, ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_WORD)},
113 {0, 0, 2, 0},
114 {1, 1, 0, 0},
115 {1, 1, 0, 0},
119 /* 68HC11 and 68HC12 registers. They are numbered according to the 68HC12. */
120 typedef enum register_id
122 REG_NONE = -1,
123 REG_A = 0,
124 REG_B = 1,
125 REG_CCR = 2,
126 REG_D = 4,
127 REG_X = 5,
128 REG_Y = 6,
129 REG_SP = 7,
130 REG_PC = 8,
131 REG_R0 = 0,
132 REG_R1 = 1,
133 REG_R2 = 2,
134 REG_R3 = 3,
135 REG_R4 = 4,
136 REG_R5 = 5,
137 REG_R6 = 6,
138 REG_R7 = 7,
139 REG_SP_XG = 8,
140 REG_PC_XG = 9,
141 REG_CCR_XG = 10
142 } register_id;
144 typedef struct operand
146 expressionS exp;
147 register_id reg1;
148 register_id reg2;
149 int mode;
150 } operand;
152 struct m68hc11_opcode_def
154 long format;
155 int min_operands;
156 int max_operands;
157 int nb_modes;
158 int used;
159 struct m68hc11_opcode *opcode;
162 static struct m68hc11_opcode_def *m68hc11_opcode_defs = 0;
163 static int m68hc11_nb_opcode_defs = 0;
165 typedef struct alias
167 const char *name;
168 const char *alias;
169 } alias;
171 static alias alias_opcodes[] =
173 {"cpd", "cmpd"},
174 {"cpx", "cmpx"},
175 {"cpy", "cmpy"},
176 {0, 0}
179 struct m9s12xg_opcode_def
181 long format;
182 int min_operands;
183 int max_operands;
184 int nb_modes;
185 int used;
186 struct m9s12xg_opcode *opcode;
189 /* Local functions. */
190 static register_id reg_name_search (char *);
191 static register_id register_name (void);
192 static int cmp_opcode (struct m68hc11_opcode *, struct m68hc11_opcode *);
193 static char *print_opcode_format (struct m68hc11_opcode *, int);
194 static char *skip_whites (char *);
195 static int check_range (long, int);
196 static void print_opcode_list (void);
197 static void get_default_target (void);
198 static void print_insn_format (char *);
199 static int get_operand (operand *, int, long);
200 static void fixup8 (expressionS *, int, int);
201 static void fixup16 (expressionS *, int, int);
202 static void fixup24 (expressionS *, int, int);
203 static void fixup8_xg (expressionS *, int, int);
204 static unsigned char convert_branch (unsigned char);
205 static char *m68hc11_new_insn (int);
206 static void build_dbranch_insn (struct m68hc11_opcode *,
207 operand *, int, int);
208 static int build_indexed_byte (operand *, int, int);
209 static int build_reg_mode (operand *, int);
211 static struct m68hc11_opcode *find (struct m68hc11_opcode_def *,
212 operand *, int);
213 static struct m68hc11_opcode *find_opcode (struct m68hc11_opcode_def *,
214 operand *, int *);
215 static void build_jump_insn (struct m68hc11_opcode *, operand *, int, int);
216 static void build_insn_xg (struct m68hc11_opcode *, operand *, int);
217 static void build_insn (struct m68hc11_opcode *, operand *, int);
218 static int relaxable_symbol (symbolS *);
220 /* Pseudo op to indicate a relax group. */
221 static void s_m68hc11_relax (int);
223 /* Pseudo op to control the ELF flags. */
224 static void s_m68hc11_mode (int);
226 /* Process directives specified via pseudo ops. */
227 static void s_m68hc11_parse_pseudo_instruction (int);
229 /* Mark the symbols with STO_M68HC12_FAR to indicate the functions
230 are using 'rtc' for returning. It is necessary to use 'call'
231 to invoke them. This is also used by the debugger to correctly
232 find the stack frame. */
233 static void s_m68hc11_mark_symbol (int);
235 /* Controls whether relative branches can be turned into long branches.
236 When the relative offset is too large, the insn are changed:
237 bra -> jmp
238 bsr -> jsr
239 bcc -> b!cc +3
240 jmp L
241 dbcc -> db!cc +3
242 jmp L
244 Setting the flag forbids this. */
245 static short flag_fixed_branches = 0;
247 /* Force to use long jumps (absolute) instead of relative branches. */
248 static short flag_force_long_jumps = 0;
250 /* Change the direct addressing mode into an absolute addressing mode
251 when the insn does not support direct addressing.
252 For example, "clr *ZD0" is normally not possible and is changed
253 into "clr ZDO". */
254 static short flag_strict_direct_addressing = 1;
256 /* When an opcode has invalid operand, print out the syntax of the opcode
257 to stderr. */
258 static short flag_print_insn_syntax = 0;
260 /* Dumps the list of instructions with syntax and then exit:
261 1 -> Only dumps the list (sorted by name)
262 2 -> Generate an example (or test) that can be compiled. */
263 static short flag_print_opcodes = 0;
265 /* Opcode hash table. */
266 static htab_t m68hc11_hash;
268 /* Current cpu (either cpu6811 or cpu6812). This is determined automagically
269 by 'get_default_target' by looking at default BFD vector. This is overridden
270 with the -m<cpu> option. */
271 static int current_architecture = 0;
273 /* Default cpu determined by 'get_default_target'. */
274 static const char *default_cpu;
276 /* Number of opcodes in the sorted table (filtered by current cpu). */
277 static int num_opcodes;
279 /* The opcodes sorted by name and filtered by current cpu. */
280 static struct m68hc11_opcode *m68hc11_sorted_opcodes;
282 /* ELF flags to set in the output file header. */
283 static int elf_flags = E_M68HC11_F64;
285 /* These are the machine dependent pseudo-ops. These are included so
286 the assembler can work on the output from the SUN C compiler, which
287 generates these. */
289 /* This table describes all the machine specific pseudo-ops the assembler
290 has to support. The fields are:
291 pseudo-op name without dot
292 function to call to execute this pseudo-op
293 Integer arg to pass to the function. */
294 const pseudo_typeS md_pseudo_table[] =
296 /* The following pseudo-ops are supported for MRI compatibility. */
297 {"fcb", cons, 1},
298 {"fdb", cons, 2},
299 {"fqb", cons, 4},
300 {"fcc", stringer, 8 + 1},
301 {"rmb", s_space, 0},
303 /* Motorola ALIS. */
304 {"xrefb", s_ignore, 0}, /* Same as xref */
306 /* Gcc driven relaxation. */
307 {"relax", s_m68hc11_relax, 0},
309 /* .mode instruction (ala SH). */
310 {"mode", s_m68hc11_mode, 0},
312 /* .far instruction. */
313 {"far", s_m68hc11_mark_symbol, STO_M68HC12_FAR},
315 /* .interrupt instruction. */
316 {"interrupt", s_m68hc11_mark_symbol, STO_M68HC12_INTERRUPT},
318 /* .nobankwarning instruction. */
319 {"nobankwarning", s_m68hc11_parse_pseudo_instruction, E_M68HC11_NO_BANK_WARNING},
321 {0, 0, 0}
324 /* Options and initialization. */
326 const char *md_shortopts = "Sm:";
328 struct option md_longopts[] =
330 #define OPTION_FORCE_LONG_BRANCH (OPTION_MD_BASE)
331 {"force-long-branches", no_argument, NULL, OPTION_FORCE_LONG_BRANCH},
332 {"force-long-branchs", no_argument, NULL, OPTION_FORCE_LONG_BRANCH}, /* Misspelled version kept for backwards compatibility. */
334 #define OPTION_SHORT_BRANCHES (OPTION_MD_BASE + 1)
335 {"short-branches", no_argument, NULL, OPTION_SHORT_BRANCHES},
336 {"short-branchs", no_argument, NULL, OPTION_SHORT_BRANCHES}, /* Misspelled version kept for backwards compatibility. */
338 #define OPTION_STRICT_DIRECT_MODE (OPTION_MD_BASE + 2)
339 {"strict-direct-mode", no_argument, NULL, OPTION_STRICT_DIRECT_MODE},
341 #define OPTION_PRINT_INSN_SYNTAX (OPTION_MD_BASE + 3)
342 {"print-insn-syntax", no_argument, NULL, OPTION_PRINT_INSN_SYNTAX},
344 #define OPTION_PRINT_OPCODES (OPTION_MD_BASE + 4)
345 {"print-opcodes", no_argument, NULL, OPTION_PRINT_OPCODES},
347 #define OPTION_GENERATE_EXAMPLE (OPTION_MD_BASE + 5)
348 {"generate-example", no_argument, NULL, OPTION_GENERATE_EXAMPLE},
350 #define OPTION_MSHORT (OPTION_MD_BASE + 6)
351 {"mshort", no_argument, NULL, OPTION_MSHORT},
353 #define OPTION_MLONG (OPTION_MD_BASE + 7)
354 {"mlong", no_argument, NULL, OPTION_MLONG},
356 #define OPTION_MSHORT_DOUBLE (OPTION_MD_BASE + 8)
357 {"mshort-double", no_argument, NULL, OPTION_MSHORT_DOUBLE},
359 #define OPTION_MLONG_DOUBLE (OPTION_MD_BASE + 9)
360 {"mlong-double", no_argument, NULL, OPTION_MLONG_DOUBLE},
362 #define OPTION_XGATE_RAMOFFSET (OPTION_MD_BASE + 10)
363 {"xgate-ramoffset", no_argument, NULL, OPTION_XGATE_RAMOFFSET},
365 {NULL, no_argument, NULL, 0}
367 size_t md_longopts_size = sizeof (md_longopts);
369 /* Get the target cpu for the assembler. This is based on the configure
370 options and on the -m68hc11/-m68hc12 option. If no option is specified,
371 we must get the default. */
372 const char *
373 m68hc11_arch_format (void)
375 get_default_target ();
376 if (current_architecture & cpu6811)
377 return "elf32-m68hc11";
378 else
379 return "elf32-m68hc12";
382 enum bfd_architecture
383 m68hc11_arch (void)
385 get_default_target ();
386 if (current_architecture & cpu6811)
387 return bfd_arch_m68hc11;
388 else
389 return bfd_arch_m68hc12;
393 m68hc11_mach (void)
395 return 0;
398 /* Listing header selected according to cpu. */
399 const char *
400 m68hc11_listing_header (void)
402 if (current_architecture & cpu6811)
403 return "M68HC11 GAS ";
404 else if (current_architecture & cpuxgate)
405 return "XGATE GAS ";
406 else if (current_architecture & cpu9s12x)
407 return "S12X GAS ";
408 else
409 return "M68HC12 GAS ";
412 void
413 md_show_usage (FILE *stream)
415 get_default_target ();
416 fprintf (stream, _("\
417 Motorola 68HC11/68HC12/68HCS12 options:\n\
418 -m68hc11 | -m68hc12 |\n\
419 -m68hcs12 | -mm9s12x |\n\
420 -mm9s12xg specify the processor [default %s]\n\
421 -mshort use 16-bit int ABI (default)\n\
422 -mlong use 32-bit int ABI\n\
423 -mshort-double use 32-bit double ABI\n\
424 -mlong-double use 64-bit double ABI (default)\n\
425 --force-long-branches always turn relative branches into absolute ones\n\
426 -S,--short-branches do not turn relative branches into absolute ones\n\
427 when the offset is out of range\n\
428 --strict-direct-mode do not turn the direct mode into extended mode\n\
429 when the instruction does not support direct mode\n\
430 --print-insn-syntax print the syntax of instruction in case of error\n\
431 --print-opcodes print the list of instructions with syntax\n\
432 --xgate-ramoffset offset ram addresses by 0xc000\n\
433 --generate-example generate an example of each instruction\n\
434 (used for testing)\n"), default_cpu);
438 /* Try to identify the default target based on the BFD library. */
439 static void
440 get_default_target (void)
442 const bfd_target *target;
443 bfd abfd;
445 if (current_architecture != 0)
446 return;
448 default_cpu = "unknown";
449 target = bfd_find_target (0, &abfd);
450 if (target && target->name)
452 if (strcmp (target->name, "elf32-m68hc12") == 0)
454 current_architecture = cpu6812;
455 default_cpu = "m68hc12";
457 else if (strcmp (target->name, "elf32-m68hc11") == 0)
459 current_architecture = cpu6811;
460 default_cpu = "m68hc11";
462 else
464 as_bad (_("Default target `%s' is not supported."), target->name);
469 void
470 m68hc11_print_statistics (FILE *file)
472 int i;
473 struct m68hc11_opcode_def *opc;
475 htab_print_statistics (file, "opcode table", m68hc11_hash);
477 opc = m68hc11_opcode_defs;
478 if (opc == 0 || m68hc11_nb_opcode_defs == 0)
479 return;
481 /* Dump the opcode statistics table. */
482 fprintf (file, _("Name # Modes Min ops Max ops Modes mask # Used\n"));
483 for (i = 0; i < m68hc11_nb_opcode_defs; i++, opc++)
485 fprintf (file, "%-7.7s %5d %7d %7d 0x%08lx %7d\n",
486 opc->opcode->name,
487 opc->nb_modes,
488 opc->min_operands, opc->max_operands, opc->format, opc->used);
493 md_parse_option (int c, const char *arg)
495 get_default_target ();
496 switch (c)
498 /* -S means keep external to 2 bit offset rather than 16 bit one. */
499 case OPTION_SHORT_BRANCHES:
500 case 'S':
501 flag_fixed_branches = 1;
502 break;
504 case OPTION_FORCE_LONG_BRANCH:
505 flag_force_long_jumps = 1;
506 break;
508 case OPTION_PRINT_INSN_SYNTAX:
509 flag_print_insn_syntax = 1;
510 break;
512 case OPTION_PRINT_OPCODES:
513 flag_print_opcodes = 1;
514 break;
516 case OPTION_STRICT_DIRECT_MODE:
517 flag_strict_direct_addressing = 0;
518 break;
520 case OPTION_GENERATE_EXAMPLE:
521 flag_print_opcodes = 2;
522 break;
524 case OPTION_MSHORT:
525 elf_flags &= ~E_M68HC11_I32;
526 break;
528 case OPTION_MLONG:
529 elf_flags |= E_M68HC11_I32;
530 break;
532 case OPTION_MSHORT_DOUBLE:
533 elf_flags &= ~E_M68HC11_F64;
534 break;
536 case OPTION_MLONG_DOUBLE:
537 elf_flags |= E_M68HC11_F64;
538 break;
540 case OPTION_XGATE_RAMOFFSET:
541 elf_flags |= E_M68HC11_XGATE_RAMOFFSET;
542 break;
544 case 'm':
545 if ((strcasecmp (arg, "68hc11") == 0)
546 || (strcasecmp (arg, "m68hc11") == 0))
547 current_architecture = cpu6811;
548 else if ((strcasecmp (arg, "68hc12") == 0)
549 || (strcasecmp (arg, "m68hc12") == 0))
550 current_architecture = cpu6812;
551 else if ((strcasecmp (arg, "68hcs12") == 0)
552 || (strcasecmp (arg, "m68hcs12") == 0))
553 current_architecture = cpu6812 | cpu6812s;
554 else if (strcasecmp (arg, "m9s12x") == 0)
555 current_architecture = cpu6812 | cpu6812s | cpu9s12x;
556 else if ((strcasecmp (arg, "m9s12xg") == 0)
557 || (strcasecmp (arg, "xgate") == 0))
558 /* xgate for backwards compatibility */
559 current_architecture = cpuxgate;
560 else
561 as_bad (_("Option `%s' is not recognized."), arg);
562 break;
564 default:
565 return 0;
568 return 1;
571 symbolS *
572 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
574 return 0;
577 const char *
578 md_atof (int type, char *litP, int *sizeP)
580 return ieee_md_atof (type, litP, sizeP, true);
583 valueT
584 md_section_align (asection *seg, valueT addr)
586 int align = bfd_section_alignment (seg);
587 return ((addr + (1 << align) - 1) & -(1 << align));
590 static int
591 cmp_opcode (struct m68hc11_opcode *op1, struct m68hc11_opcode *op2)
593 return strcmp (op1->name, op2->name);
596 #define IS_CALL_SYMBOL(MODE) \
597 (((MODE) & (M6812_OP_PAGE|M6811_OP_IND16)) \
598 == ((M6812_OP_PAGE|M6811_OP_IND16)))
600 /* Initialize the assembler. Create the opcode hash table
601 (sorted on the names) with the M6811 opcode table
602 (from opcode library). */
603 void
604 md_begin (void)
606 const char *prev_name = "";
607 struct m68hc11_opcode *opcodes;
608 struct m68hc11_opcode_def *opc = 0;
609 int i, j;
611 get_default_target ();
613 m68hc11_hash = str_htab_create ();
615 /* Get a writable copy of the opcode table and sort it on the names. */
616 opcodes = XNEWVEC (struct m68hc11_opcode, m68hc11_num_opcodes);
617 m68hc11_sorted_opcodes = opcodes;
618 num_opcodes = 0;
619 for (i = 0; i < m68hc11_num_opcodes; i++)
621 if (m68hc11_opcodes[i].arch & current_architecture)
623 opcodes[num_opcodes] = m68hc11_opcodes[i];
624 if (opcodes[num_opcodes].name[0] == 'b'
625 && opcodes[num_opcodes].format & M6811_OP_JUMP_REL
626 && !(opcodes[num_opcodes].format & M6811_OP_BITMASK))
628 num_opcodes++;
629 opcodes[num_opcodes] = m68hc11_opcodes[i];
631 num_opcodes++;
632 for (j = 0; alias_opcodes[j].name != 0; j++)
633 if (strcmp (m68hc11_opcodes[i].name, alias_opcodes[j].name) == 0)
635 opcodes[num_opcodes] = m68hc11_opcodes[i];
636 opcodes[num_opcodes].name = alias_opcodes[j].alias;
637 num_opcodes++;
638 break;
642 qsort (opcodes, num_opcodes, sizeof (struct m68hc11_opcode),
643 (int (*) (const void*, const void*)) cmp_opcode);
645 opc = XNEWVEC (struct m68hc11_opcode_def, num_opcodes);
646 m68hc11_opcode_defs = opc;
648 /* Insert unique names into hash table. The M6811 instruction set
649 has several identical opcode names that have different opcodes based
650 on the operands. This hash table then provides a quick index to
651 the first opcode with a particular name in the opcode table. */
652 for (i = 0; i < num_opcodes; i++, opcodes++)
654 int expect;
656 if (strcmp (prev_name, opcodes->name))
658 prev_name = opcodes->name;
659 opc++;
660 (opc - 1)->format = 0;
661 (opc - 1)->min_operands = 100;
662 (opc - 1)->max_operands = 0;
663 (opc - 1)->nb_modes = 0;
664 (opc - 1)->opcode = opcodes;
665 (opc - 1)->used = 0;
666 str_hash_insert (m68hc11_hash, opcodes->name, opc - 1, 0);
668 (opc - 1)->nb_modes++;
669 (opc - 1)->format |= opcodes->format;
671 /* See how many operands this opcode needs. */
672 expect = 0;
673 if (opcodes->arch == cpuxgate)
675 if (opcodes->format & (M68XG_OP_IMM3 | M68XG_OP_R | M68XG_OP_REL9
676 | M68XG_OP_REL10 ))
677 expect = 1;
678 else if (opcodes->format & (M68XG_OP_R_R | M68XG_OP_R_IMM4
679 | M68XG_OP_R_IMM8 | M68XG_OP_R_IMM8))
680 expect = 2;
681 else if (opcodes->format & (M68XG_OP_R_R_R | M68XG_OP_R_R_OFFS5
682 | M68XG_OP_RD_RB_RI | M68XG_OP_RD_RB_RIp
683 | M68XG_OP_RD_RB_mRI))
684 expect = 3;
686 else
688 if (opcodes->format & M6811_OP_MASK)
689 expect++;
690 if (opcodes->format & M6811_OP_BITMASK)
691 expect++;
692 if (opcodes->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
693 expect++;
694 if (opcodes->format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2))
695 expect++;
696 /* Special case for call instruction. */
697 if ((opcodes->format & M6812_OP_PAGE)
698 && !(opcodes->format & M6811_OP_IND16))
699 expect++;
702 if (expect < (opc - 1)->min_operands)
703 (opc - 1)->min_operands = expect;
704 if (IS_CALL_SYMBOL (opcodes->format))
705 expect++;
706 if (expect > (opc - 1)->max_operands)
707 (opc - 1)->max_operands = expect;
709 m68hc11_nb_opcode_defs = opc - m68hc11_opcode_defs;
711 if (flag_print_opcodes)
713 print_opcode_list ();
714 exit (EXIT_SUCCESS);
718 void
719 m68hc11_init_after_args (void)
723 /* Builtin help. */
725 /* Return a string that represents the operand format for the instruction.
726 When example is true, this generates an example of operand. This is used
727 to give an example and also to generate a test. */
729 static char *
730 print_opcode_format (struct m68hc11_opcode *opcode, int example)
732 static char buf[128];
733 int format = opcode->format;
734 char *p;
736 p = buf;
737 buf[0] = 0;
739 if (current_architecture == cpuxgate)
741 if (format & M68XG_OP_IMM3)
743 if (example)
744 sprintf (p, "#%d", rand () & 0x007);
745 else
746 strcpy (p, _("imm3"));
747 p = &p[strlen (p)];
749 else if (format & M68XG_OP_R)
751 if (example)
752 sprintf (p, "R%d", rand () & 0x07);
753 else
754 strcpy (p, _("RD"));
755 p = &p[strlen (p)];
757 else if (format & M68XG_OP_R_R)
759 if (example)
760 sprintf (p, "R%d,R%d", rand () & 0x07, rand () & 0x07);
761 else
762 strcpy (p, _("RD,RS"));
763 p = &p[strlen (p)];
765 else if (format & M68XG_OP_R_IMM4)
767 if (example)
768 sprintf (p, "R%d,#%d", rand () & 0x07, rand () & 0x0f);
769 else
770 strcpy (p, _("RI, #imm4"));
771 p = &p[strlen (p)];
773 else if (format & M68XG_OP_R_R_R)
775 if (example)
776 sprintf (p, "R%d,R%d,R%d", rand () & 0x07, rand () & 0x07, rand () & 0x07);
777 else
778 strcpy (p, "RD,RS1,RS2");
779 p = &p[strlen (p)];
781 else if (format & M68XG_OP_REL9)
783 if (example)
784 sprintf (p, "%d", rand () & 0x1FF);
785 else
786 strcpy (p, "<rel9>");
787 p = &p[strlen (p)];
789 else if (format & M68XG_OP_REL10)
791 if (example)
792 sprintf (p, "%d", rand () & 0x3FF);
793 else
794 strcpy (p, "<rel10>");
795 p = &p[strlen (p)];
797 else if (format & M68XG_OP_R_R_OFFS5)
799 if (example)
800 sprintf (p, "R%d, (R%d, #0x%x)", rand () & 0x07, rand () & 0x07, rand () & 0x1f);
801 else
802 strcpy (p, _("RD, (RI,#offs5)"));
803 p = &p[strlen (p)];
805 else if (format & M68XG_OP_RD_RB_RI)
807 if (example)
808 sprintf (p, "R%d, (R%d, R%d)", rand () & 0x07, rand () & 0x07, rand () & 0x07);
809 else
810 strcpy (p, "RD, (RB, RI)");
811 p = &p[strlen (p)];
813 else if (format & M68XG_OP_RD_RB_RIp)
815 if (example)
816 sprintf (p, "R%d, (R%d, R%d+)", rand () & 0x07, rand () & 0x07, rand () & 0x07);
817 else
818 strcpy (p, "RD, (RB, RI+)");
819 p = &p[strlen (p)];
821 else if (format & M68XG_OP_RD_RB_mRI)
823 if (example)
824 sprintf (p, "R%d, (R%d, -R%d)", rand () & 0x07, rand () & 0x07, rand () & 0x07);
825 else
826 strcpy (p, "RD, (RB, -RI)");
827 p = &p[strlen (p)];
829 else if (format & M68XG_OP_R_IMM8)
831 if (example)
832 sprintf (p, "R%d, #0x%x", rand () & 0x07, rand () & 0xff);
833 else
834 strcpy (p, "RD, #imm8");
835 p = &p[strlen (p)];
837 else if (format & M68XG_OP_R_IMM16)
839 if (example)
840 sprintf (p, "R%d, #0x%x", rand () & 0x07, rand () & 0xffff);
841 else
842 strcpy (p, "RD, #imm16");
843 p = &p[strlen (p)];
846 else
849 if (format & M6811_OP_IMM8)
851 if (example)
852 sprintf (p, "#%d", rand () & 0x0FF);
853 else
854 strcpy (p, _("#<imm8>"));
855 p = &p[strlen (p)];
858 if (format & M6811_OP_IMM16)
860 if (example)
861 sprintf (p, "#%d", rand () & 0x0FFFF);
862 else
863 strcpy (p, _("#<imm16>"));
864 p = &p[strlen (p)];
867 if (format & M6811_OP_IX)
869 if (example)
870 sprintf (p, "%d,X", rand () & 0x0FF);
871 else
872 strcpy (p, _("<imm8>,X"));
873 p = &p[strlen (p)];
876 if (format & M6811_OP_IY)
878 if (example)
879 sprintf (p, "%d,X", rand () & 0x0FF);
880 else
881 strcpy (p, _("<imm8>,X"));
882 p = &p[strlen (p)];
885 if (format & M6812_OP_IDX)
887 if (example)
888 sprintf (p, "%d,X", rand () & 0x0FF);
889 else
890 strcpy (p, "n,r");
891 p = &p[strlen (p)];
894 if (format & M6812_OP_PAGE)
896 if (example)
897 sprintf (p, ", %d", rand () & 0x0FF);
898 else
899 strcpy (p, ", <page>");
900 p = &p[strlen (p)];
903 if (format & M6811_OP_DIRECT)
905 if (example)
906 sprintf (p, "*Z%d", rand () & 0x0FF);
907 else
908 strcpy (p, _("*<abs8>"));
909 p = &p[strlen (p)];
912 if (format & M6811_OP_BITMASK)
914 if (buf[0])
915 *p++ = ' ';
917 if (example)
918 sprintf (p, "#$%02x", rand () & 0x0FF);
919 else
920 strcpy (p, _("#<mask>"));
922 p = &p[strlen (p)];
923 if (format & M6811_OP_JUMP_REL)
924 *p++ = ' ';
927 if (format & M6811_OP_IND16)
929 if (example)
930 sprintf (p, _("symbol%d"), rand () & 0x0FF);
931 else
932 strcpy (p, _("<abs>"));
934 p = &p[strlen (p)];
937 if (format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
939 if (example)
941 if (format & M6811_OP_BITMASK)
943 sprintf (p, ".+%d", rand () & 0x7F);
945 else
947 sprintf (p, "L%d", rand () & 0x0FF);
950 else
951 strcpy (p, _("<label>"));
954 return buf;
957 /* Prints the list of instructions with the possible operands. */
958 static void
959 print_opcode_list (void)
961 int i;
962 const char *prev_name = "";
963 struct m68hc11_opcode *opcodes;
964 int example = flag_print_opcodes == 2;
966 if (example)
967 printf (_("# Example of `%s' instructions\n\t.sect .text\n_start:\n"),
968 default_cpu);
970 opcodes = m68hc11_sorted_opcodes;
972 /* Walk the list sorted on names (by md_begin). We only report
973 one instruction per line, and we collect the different operand
974 formats. */
975 for (i = 0; i < num_opcodes; i++, opcodes++)
977 char *fmt = print_opcode_format (opcodes, example);
979 if (example)
981 printf ("L%d:\t", i);
982 printf ("%s %s\n", opcodes->name, fmt);
984 else
986 if (strcmp (prev_name, opcodes->name))
988 if (i > 0)
989 printf ("\n");
991 printf ("%-5.5s ", opcodes->name);
992 prev_name = (char *) opcodes->name;
994 if (fmt[0])
995 printf (" [%s]", fmt);
998 printf ("\n");
1001 /* Print the instruction format. This operation is called when some
1002 instruction is not correct. Instruction format is printed as an
1003 error message. */
1004 static void
1005 print_insn_format (char *name)
1007 struct m68hc11_opcode_def *opc;
1008 struct m68hc11_opcode *opcode;
1009 char buf[128];
1011 opc = (struct m68hc11_opcode_def *) str_hash_find (m68hc11_hash, name);
1012 if (opc == NULL)
1014 as_bad (_("Instruction `%s' is not recognized."), name);
1015 return;
1017 opcode = opc->opcode;
1019 as_bad (_("Instruction formats for `%s':"), name);
1022 char *fmt;
1024 fmt = print_opcode_format (opcode, 0);
1025 sprintf (buf, "\t%-5.5s %s", opcode->name, fmt);
1027 as_bad ("%s", buf);
1028 opcode++;
1030 while (strcmp (opcode->name, name) == 0);
1033 /* Analysis of 68HC11 and 68HC12 operands. */
1035 /* reg_name_search() finds the register number given its name.
1036 Returns the register number or REG_NONE on failure. */
1037 static register_id
1038 reg_name_search (char *name)
1040 if (strcasecmp (name, "x") == 0 || strcasecmp (name, "ix") == 0)
1041 return REG_X;
1042 if (strcasecmp (name, "y") == 0 || strcasecmp (name, "iy") == 0)
1043 return REG_Y;
1044 if (strcasecmp (name, "a") == 0)
1045 return REG_A;
1046 if (strcasecmp (name, "b") == 0)
1047 return REG_B;
1048 if (strcasecmp (name, "d") == 0)
1049 return REG_D;
1050 if (strcasecmp (name, "sp") == 0)
1051 return REG_SP;
1052 if (strcasecmp (name, "pc") == 0)
1053 return REG_PC;
1054 if (strcasecmp (name, "ccr") == 0)
1055 return REG_CCR;
1056 /* XGATE */
1057 if (strcasecmp (name, "r0") == 0)
1058 return REG_R0;
1059 if (strcasecmp (name, "r1") == 0)
1060 return REG_R1;
1061 if (strcasecmp (name, "r2") == 0)
1062 return REG_R2;
1063 if (strcasecmp (name, "r3") == 0)
1064 return REG_R3;
1065 if (strcasecmp (name, "r4") == 0)
1066 return REG_R4;
1067 if (strcasecmp (name, "r5") == 0)
1068 return REG_R5;
1069 if (strcasecmp (name, "r6") == 0)
1070 return REG_R6;
1071 if (strcasecmp (name, "r7") == 0)
1072 return REG_R7;
1073 if (strcasecmp (name, "sp") == 0)
1074 return REG_SP_XG;
1075 if (strcasecmp (name, "pc") == 0)
1076 return REG_PC_XG;
1077 if (strcasecmp (name, "ccr") == 0)
1078 return REG_CCR_XG;
1079 return REG_NONE;
1082 static char *
1083 skip_whites (char *p)
1085 while (*p == ' ' || *p == '\t')
1086 p++;
1088 return p;
1091 /* Check the string at input_line_pointer
1092 to see if it is a valid register name. */
1093 static register_id
1094 register_name (void)
1096 register_id reg_number;
1097 char c, *p = input_line_pointer;
1099 if (!is_name_beginner (*p++))
1100 return REG_NONE;
1102 while (is_part_of_name (*p++))
1103 continue;
1105 c = *--p;
1106 if (c)
1107 *p++ = 0;
1109 /* Look to see if it's in the register table. */
1110 reg_number = reg_name_search (input_line_pointer);
1111 if (reg_number != REG_NONE)
1113 if (c)
1114 *--p = c;
1116 input_line_pointer = p;
1117 return reg_number;
1119 if (c)
1120 *--p = c;
1122 return reg_number;
1124 #define M6811_OP_CALL_ADDR 0x00800000
1125 #define M6811_OP_PAGE_ADDR 0x04000000
1127 /* Parse a string of operands and return an array of expressions.
1129 Operand mode[0] mode[1] exp[0] exp[1]
1130 #n M6811_OP_IMM16 - O_*
1131 *<exp> M6811_OP_DIRECT - O_*
1132 .{+-}<exp> M6811_OP_JUMP_REL - O_*
1133 <exp> M6811_OP_IND16 - O_*
1134 ,r N,r M6812_OP_IDX M6812_OP_REG O_constant O_register
1135 n,-r M6812_PRE_DEC M6812_OP_REG O_constant O_register
1136 n,+r M6812_PRE_INC " "
1137 n,r- M6812_POST_DEC " "
1138 n,r+ M6812_POST_INC " "
1139 A,r B,r D,r M6811_OP_REG M6812_OP_REG O_register O_register
1140 [D,r] M6811_OP_D_IDX M6812_OP_REG O_register O_register
1141 [n,r] M6811_OP_D_IDX_2 M6812_OP_REG O_constant O_register */
1142 static int
1143 get_operand (operand *oper, int which, long opmode)
1145 char *p = input_line_pointer;
1146 int mode;
1147 register_id reg;
1149 oper->exp.X_op = O_absent;
1150 oper->reg1 = REG_NONE;
1151 oper->reg2 = REG_NONE;
1152 mode = M6811_OP_NONE;
1154 p = skip_whites (p);
1156 if (*p == 0 || *p == '\n' || *p == '\r')
1158 input_line_pointer = p;
1159 return 0;
1162 if (*p == '*' && (opmode & (M6811_OP_DIRECT | M6811_OP_IND16)))
1164 mode = M6811_OP_DIRECT;
1165 p++;
1167 else if (*p == '#')
1169 if (!(opmode & (M6811_OP_IMM8 | M6811_OP_IMM16 | M6811_OP_BITMASK)))
1171 as_bad (_("Immediate operand is not allowed for operand %d."),
1172 which);
1173 return -1;
1176 mode = M6811_OP_IMM16;
1177 p++;
1178 if (startswith (p, "%hi"))
1180 p += 3;
1181 mode |= M6811_OP_HIGH_ADDR;
1183 else if (startswith (p, "%lo"))
1185 p += 3;
1186 mode |= M6811_OP_LOW_ADDR;
1188 /* %page modifier is used to obtain only the page number
1189 of the address of a function. */
1190 else if (startswith (p, "%page"))
1192 p += 5;
1193 mode |= M6811_OP_PAGE_ADDR;
1196 /* %addr modifier is used to obtain the physical address part
1197 of the function (16-bit). For 68HC12 the function will be
1198 mapped in the 16K window at 0x8000 and the value will be
1199 within that window (although the function address may not fit
1200 in 16-bit). See bfd/elf32-m68hc12.c for the translation. */
1201 else if (startswith (p, "%addr"))
1203 p += 5;
1204 mode |= M6811_OP_CALL_ADDR;
1207 else if (*p == '.' && (p[1] == '+' || p[1] == '-'))
1209 p++;
1210 mode = M6811_OP_JUMP_REL;
1212 else if (*p == '[')
1214 if (current_architecture & cpu6811)
1215 as_bad (_("Indirect indexed addressing is not valid for 68HC11."));
1217 p++;
1218 mode = M6812_OP_D_IDX;
1219 p = skip_whites (p);
1221 else if (*p == ',') /* Special handling of ,x and ,y. */
1223 p++;
1224 input_line_pointer = p;
1226 reg = register_name ();
1227 if (reg != REG_NONE)
1229 oper->reg1 = reg;
1230 oper->exp.X_op = O_constant;
1231 oper->exp.X_add_number = 0;
1232 oper->mode = M6812_OP_IDX;
1233 return 1;
1235 as_bad (_("Spurious `,' or bad indirect register addressing mode."));
1236 return -1;
1238 /* Handle 68HC12 page specification in 'call foo,%page(bar)'. */
1239 else if ((opmode & M6812_OP_PAGE) && startswith (p, "%page"))
1241 p += 5;
1242 mode = M6811_OP_PAGE_ADDR | M6812_OP_PAGE | M6811_OP_IND16;
1244 input_line_pointer = p;
1246 if (mode == M6811_OP_NONE || mode == M6812_OP_D_IDX)
1247 reg = register_name ();
1248 else
1249 reg = REG_NONE;
1251 if (reg != REG_NONE)
1253 p = skip_whites (input_line_pointer);
1254 if (*p == ']' && mode == M6812_OP_D_IDX)
1256 as_bad
1257 (_("Missing second register or offset for indexed-indirect mode."));
1258 return -1;
1261 oper->reg1 = reg;
1262 oper->mode = mode | M6812_OP_REG;
1263 if (*p != ',')
1265 if (mode == M6812_OP_D_IDX)
1267 as_bad (_("Missing second register for indexed-indirect mode."));
1268 return -1;
1270 return 1;
1273 p++;
1274 input_line_pointer = p;
1275 reg = register_name ();
1276 if (reg != REG_NONE)
1278 p = skip_whites (input_line_pointer);
1279 if (mode == M6812_OP_D_IDX)
1281 if (*p != ']')
1283 as_bad (_("Missing `]' to close indexed-indirect mode."));
1284 return -1;
1286 p++;
1287 oper->mode = M6812_OP_D_IDX;
1289 input_line_pointer = p;
1291 oper->reg2 = reg;
1292 return 1;
1294 return 1;
1297 /* In MRI mode, isolate the operand because we can't distinguish
1298 operands from comments. */
1299 if (flag_mri)
1301 char c = 0;
1303 p = skip_whites (p);
1304 while (*p && *p != ' ' && *p != '\t')
1305 p++;
1307 if (*p)
1309 c = *p;
1310 *p = 0;
1313 /* Parse as an expression. */
1314 expression (&oper->exp);
1316 if (c)
1318 *p = c;
1321 else
1323 expression (&oper->exp);
1326 if (oper->exp.X_op == O_illegal)
1328 as_bad (_("Illegal operand."));
1329 return -1;
1331 else if (oper->exp.X_op == O_absent)
1333 as_bad (_("Missing operand."));
1334 return -1;
1337 p = input_line_pointer;
1339 if (mode == M6811_OP_NONE || mode == M6811_OP_DIRECT
1340 || mode == M6812_OP_D_IDX)
1342 p = skip_whites (input_line_pointer);
1344 if (*p == ',')
1346 int possible_mode = M6811_OP_NONE;
1347 char *old_input_line;
1349 old_input_line = p;
1350 p++;
1352 /* 68HC12 pre increment or decrement. */
1353 if (mode == M6811_OP_NONE)
1355 if (*p == '-')
1357 possible_mode = M6812_PRE_DEC;
1358 p++;
1360 else if (*p == '+')
1362 possible_mode = M6812_PRE_INC;
1363 p++;
1365 p = skip_whites (p);
1367 input_line_pointer = p;
1368 reg = register_name ();
1370 /* Backtrack if we have a valid constant expression and
1371 it does not correspond to the offset of the 68HC12 indexed
1372 addressing mode (as in N,x). */
1373 if (reg == REG_NONE && mode == M6811_OP_NONE
1374 && possible_mode != M6811_OP_NONE)
1376 oper->mode = M6811_OP_IND16 | M6811_OP_JUMP_REL;
1377 input_line_pointer = skip_whites (old_input_line);
1378 return 1;
1381 if (possible_mode != M6811_OP_NONE)
1382 mode = possible_mode;
1384 if ((current_architecture & cpu6811)
1385 && possible_mode != M6811_OP_NONE)
1386 as_bad (_("Pre-increment mode is not valid for 68HC11"));
1387 /* Backtrack. */
1388 if (which == 0 && opmode & M6812_OP_IDX_P2
1389 && reg != REG_X && reg != REG_Y
1390 && reg != REG_PC && reg != REG_SP)
1392 reg = REG_NONE;
1393 input_line_pointer = p;
1396 if (reg == REG_NONE && mode != M6811_OP_DIRECT
1397 && !(mode == M6811_OP_NONE && opmode & M6811_OP_IND16))
1399 as_bad (_("Wrong register in register indirect mode."));
1400 return -1;
1402 if (mode == M6812_OP_D_IDX)
1404 p = skip_whites (input_line_pointer);
1405 if (*p++ != ']')
1407 as_bad (_("Missing `]' to close register indirect operand."));
1408 return -1;
1410 input_line_pointer = p;
1411 oper->reg1 = reg;
1412 oper->mode = M6812_OP_D_IDX_2;
1413 return 1;
1415 if (reg != REG_NONE)
1417 oper->reg1 = reg;
1418 if (mode == M6811_OP_NONE)
1420 p = input_line_pointer;
1421 if (*p == '-')
1423 mode = M6812_POST_DEC;
1424 p++;
1425 if (current_architecture & cpu6811)
1426 as_bad
1427 (_("Post-decrement mode is not valid for 68HC11."));
1429 else if (*p == '+')
1431 mode = M6812_POST_INC;
1432 p++;
1433 if (current_architecture & cpu6811)
1434 as_bad
1435 (_("Post-increment mode is not valid for 68HC11."));
1437 else
1438 mode = M6812_OP_IDX;
1440 input_line_pointer = p;
1442 else
1443 mode |= M6812_OP_IDX;
1445 oper->mode = mode;
1446 return 1;
1448 input_line_pointer = old_input_line;
1451 if (mode == M6812_OP_D_IDX_2)
1453 as_bad (_("Invalid indexed indirect mode."));
1454 return -1;
1458 /* If the mode is not known until now, this is either a label
1459 or an indirect address. */
1460 if (mode == M6811_OP_NONE)
1461 mode = M6811_OP_IND16 | M6811_OP_JUMP_REL;
1463 p = input_line_pointer;
1464 while (*p == ' ' || *p == '\t')
1465 p++;
1466 input_line_pointer = p;
1467 oper->mode = mode;
1469 return 1;
1472 #define M6812_AUTO_INC_DEC (M6812_PRE_INC | M6812_PRE_DEC \
1473 | M6812_POST_INC | M6812_POST_DEC)
1475 /* Checks that the number 'num' fits for a given mode. */
1476 static int
1477 check_range (long num, int mode)
1479 if (current_architecture == cpuxgate)
1481 switch (mode)
1483 case M68XG_OP_IMM3:
1484 return (num >= 0 && num <= 7) ? 1 : 0;
1486 case M68XG_OP_R_IMM4:
1487 return (num >= 0 && num <= 15) ? 1 : 0;
1489 case M68XG_OP_R_R_OFFS5:
1490 return (num >= 0 && num <= 31) ? 1 : 0;
1492 case M68XG_OP_R_IMM8:
1493 return (num >= 0 && num <= 255) ? 1 : 0;
1495 case M68XG_OP_R_IMM16:
1496 return (num >= 0 && num <= 65535) ? 1 : 0;
1498 case M68XG_OP_B_MARKER:
1499 return (num >= -512 && num <= 511) ? 1 : 0;
1501 case M68XG_OP_BRA_MARKER:
1502 return (num >= -1024 && num <= 1023) ? 1 : 0;
1504 default:
1505 return 0;
1508 else
1510 /* Auto increment and decrement are ok for [-8..8] without 0. */
1511 if (mode & M6812_AUTO_INC_DEC)
1512 return (num != 0 && num <= 8 && num >= -8);
1514 /* The 68HC12 supports 5, 9 and 16-bit offsets. */
1515 if (mode & (M6812_INDEXED_IND | M6812_INDEXED | M6812_OP_IDX))
1516 mode = M6811_OP_IND16;
1518 if (mode & M6812_OP_JUMP_REL16)
1519 mode = M6811_OP_IND16;
1521 mode &= ~M6811_OP_BRANCH;
1522 switch (mode)
1524 case M6811_OP_IX:
1525 case M6811_OP_IY:
1526 case M6811_OP_DIRECT:
1527 return (num >= 0 && num <= 255) ? 1 : 0;
1529 case M6811_OP_BITMASK:
1530 case M6811_OP_IMM8:
1531 case M6812_OP_PAGE:
1532 return (((num & 0xFFFFFF00) == 0) || ((num & 0xFFFFFF00) == 0xFFFFFF00))
1533 ? 1 : 0;
1535 case M6811_OP_JUMP_REL:
1536 return (num >= -128 && num <= 127) ? 1 : 0;
1538 case M6811_OP_IND16:
1539 case M6811_OP_IND16 | M6812_OP_PAGE:
1540 case M6811_OP_IMM16:
1541 return (((num & 0xFFFF0000) == 0) || ((num & 0xFFFF0000) == 0xFFFF0000))
1542 ? 1 : 0;
1544 case M6812_OP_IBCC_MARKER:
1545 case M6812_OP_TBCC_MARKER:
1546 case M6812_OP_DBCC_MARKER:
1547 return (num >= -256 && num <= 255) ? 1 : 0;
1549 case M6812_OP_TRAP_ID:
1550 return ((num >= 0x30 && num <= 0x39)
1551 || (num >= 0x40 && num <= 0x0ff)) ? 1 : 0;
1553 default:
1554 return 0;
1559 /* Gas fixup generation. */
1561 /* Put a 1 byte expression described by 'oper'. If this expression contains
1562 unresolved symbols, generate an 8-bit fixup. */
1563 static void
1564 fixup8 (expressionS *oper, int mode, int opmode)
1566 char *f;
1568 f = frag_more (1);
1570 if (oper->X_op == O_constant)
1572 if (mode & M6812_OP_TRAP_ID
1573 && !check_range (oper->X_add_number, M6812_OP_TRAP_ID))
1575 static char trap_id_warn_once = 0;
1577 as_bad (_("Trap id `%ld' is out of range."), oper->X_add_number);
1578 if (trap_id_warn_once == 0)
1580 trap_id_warn_once = 1;
1581 as_bad (_("Trap id must be within [0x30..0x39] or [0x40..0xff]."));
1585 if (!(mode & M6812_OP_TRAP_ID)
1586 && !check_range (oper->X_add_number, mode))
1588 as_bad (_("Operand out of 8-bit range: `%ld'."), oper->X_add_number);
1590 number_to_chars_bigendian (f, oper->X_add_number & 0x0FF, 1);
1592 else if (oper->X_op != O_register)
1594 if (mode & M6812_OP_TRAP_ID)
1595 as_bad (_("The trap id must be a constant."));
1597 if (mode == M6811_OP_JUMP_REL)
1599 fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
1600 oper, true, BFD_RELOC_8_PCREL);
1602 else
1604 fixS *fixp;
1605 bfd_reloc_code_real_type reloc;
1607 /* Now create an 8-bit fixup. If there was some %hi, %lo
1608 or %page modifier, generate the reloc accordingly. */
1609 if (opmode & M6811_OP_HIGH_ADDR)
1610 reloc = BFD_RELOC_M68HC11_HI8;
1611 else if (opmode & M6811_OP_LOW_ADDR)
1612 reloc = BFD_RELOC_M68HC11_LO8;
1613 else if (opmode & M6811_OP_PAGE_ADDR)
1614 reloc = BFD_RELOC_M68HC11_PAGE;
1615 else
1616 reloc = BFD_RELOC_8;
1618 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
1619 oper, false, reloc);
1620 if (reloc != BFD_RELOC_8)
1621 fixp->fx_no_overflow = 1;
1623 number_to_chars_bigendian (f, 0, 1);
1625 else
1627 as_fatal (_("Operand `%x' not recognized in fixup8."), oper->X_op);
1631 /* Put a 2 byte expression described by 'oper'. If this expression contains
1632 unresolved symbols, generate a 16-bit fixup. */
1633 static void
1634 fixup16 (expressionS *oper, int mode, int opmode ATTRIBUTE_UNUSED)
1636 char *f;
1638 f = frag_more (2);
1640 if (oper->X_op == O_constant)
1642 if (!check_range (oper->X_add_number, mode))
1644 as_bad (_("Operand out of 16-bit range: `%ld'."),
1645 oper->X_add_number);
1647 number_to_chars_bigendian (f, oper->X_add_number & 0x0FFFF, 2);
1649 else if (oper->X_op != O_register)
1651 fixS *fixp;
1652 bfd_reloc_code_real_type reloc;
1654 if ((opmode & M6811_OP_CALL_ADDR) && (mode & M6811_OP_IMM16))
1655 reloc = BFD_RELOC_M68HC11_LO16;
1656 else if (mode & M6812_OP_JUMP_REL16)
1657 reloc = BFD_RELOC_16_PCREL;
1658 else if (mode & M6812_OP_PAGE)
1659 reloc = BFD_RELOC_M68HC11_LO16;
1660 else
1661 reloc = BFD_RELOC_16;
1663 /* Now create a 16-bit fixup. */
1664 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 2,
1665 oper,
1666 reloc == BFD_RELOC_16_PCREL,
1667 reloc);
1668 number_to_chars_bigendian (f, 0, 2);
1670 if (reloc == BFD_RELOC_M68HC11_LO16)
1671 fixp->fx_no_overflow = 1;
1673 else
1675 as_fatal (_("Operand `%x' not recognized in fixup16."), oper->X_op);
1679 /* Put a 3 byte expression described by 'oper'. If this expression contains
1680 unresolved symbols, generate a 24-bit fixup. */
1681 static void
1682 fixup24 (expressionS *oper, int mode, int opmode ATTRIBUTE_UNUSED)
1684 char *f;
1686 f = frag_more (3);
1688 if (oper->X_op == O_constant)
1690 if (!check_range (oper->X_add_number, mode))
1692 as_bad (_("Operand out of 16-bit range: `%ld'."),
1693 oper->X_add_number);
1695 number_to_chars_bigendian (f, oper->X_add_number & 0x0FFFFFF, 3);
1697 else if (oper->X_op != O_register)
1699 /* Now create a 24-bit fixup. */
1700 fix_new_exp (frag_now, f - frag_now->fr_literal, 3,
1701 oper, false, BFD_RELOC_M68HC11_24);
1702 number_to_chars_bigendian (f, 0, 3);
1704 else
1706 as_fatal (_("Operand `%x' not recognized in fixup16."), oper->X_op);
1710 /* XGATE Put a 1 byte expression described by 'oper'. If this expression
1711 contains unresolved symbols, generate an 8-bit fixup. */
1712 static void
1713 fixup8_xg (expressionS *oper, int mode, int opmode)
1715 char *f;
1717 f = frag_more (1);
1719 if (oper->X_op == O_constant)
1721 fixS *fixp;
1722 bfd_reloc_code_real_type reloc;
1724 if ((opmode & M6811_OP_HIGH_ADDR) || (opmode & M6811_OP_LOW_ADDR))
1726 if (opmode & M6811_OP_HIGH_ADDR)
1727 reloc = BFD_RELOC_M68HC11_HI8;
1728 else
1729 reloc = BFD_RELOC_M68HC11_LO8;
1731 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
1732 oper, false, reloc);
1733 fixp->fx_no_overflow = 1;
1734 number_to_chars_bigendian (f, 0, 1);
1736 else
1738 if (!(check_range (oper->X_add_number, mode)))
1739 as_bad (_("Operand out of 8-bit range: `%ld'."),
1740 oper->X_add_number);
1741 number_to_chars_bigendian (f, oper->X_add_number & 0x0FF, 1);
1744 else if (oper->X_op != O_register)
1746 if (mode == M68XG_OP_REL9)
1748 /* Future improvement:
1749 This fixup/reloc isn't adding on constants to symbols. */
1750 fix_new_exp (frag_now, f - frag_now->fr_literal -1, 2,
1751 oper, true, BFD_RELOC_M68HC12_9_PCREL);
1753 else if (mode == M68XG_OP_REL10)
1755 /* Future improvement:
1756 This fixup/reloc isn't adding on constants to symbols. */
1757 fix_new_exp (frag_now, f - frag_now->fr_literal -1, 2,
1758 oper, true, BFD_RELOC_M68HC12_10_PCREL);
1760 else
1762 fixS *fixp;
1763 bfd_reloc_code_real_type reloc;
1765 /* Now create an 8-bit fixup. If there was some %hi, %lo
1766 modifier, generate the reloc accordingly. */
1767 if (opmode & M6811_OP_HIGH_ADDR)
1768 reloc = BFD_RELOC_M68HC11_HI8;
1769 else if (opmode & M6811_OP_LOW_ADDR)
1770 reloc = BFD_RELOC_M68HC11_LO8;
1771 else
1772 reloc = BFD_RELOC_8;
1774 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
1775 oper, false, reloc);
1776 if (reloc != BFD_RELOC_8)
1777 fixp->fx_no_overflow = 1;
1779 number_to_chars_bigendian (f, 0, 1);
1781 else
1782 as_fatal (_("Operand `%x' not recognized in fixup8."), oper->X_op);
1785 /* 68HC11 and 68HC12 code generation. */
1787 /* Translate the short branch/bsr instruction into a long branch. */
1789 static unsigned char
1790 convert_branch (unsigned char code)
1792 if (IS_OPCODE (code, M6812_BSR))
1793 return M6812_JSR;
1794 else if (IS_OPCODE (code, M6811_BSR))
1795 return M6811_JSR;
1796 else if (IS_OPCODE (code, M6811_BRA))
1797 return (current_architecture & cpu6812) ? M6812_JMP : M6811_JMP;
1798 else
1799 as_fatal (_("Unexpected branch conversion with `%x'"), code);
1801 /* Keep gcc happy. */
1802 return M6811_JSR;
1805 /* Start a new insn that contains at least 'size' bytes. Record the
1806 line information of that insn in the dwarf2 debug sections. */
1807 static char *
1808 m68hc11_new_insn (int size)
1810 char *f;
1812 f = frag_more (size);
1814 dwarf2_emit_insn (size);
1816 return f;
1819 /* Builds a jump instruction (bra, bcc, bsr). */
1820 static void
1821 build_jump_insn (struct m68hc11_opcode *opcode, operand operands[],
1822 int nb_operands, int jmp_mode)
1824 unsigned char code;
1825 char *f;
1826 unsigned long n;
1828 /* The relative branch conversion is not supported for
1829 brclr and brset. */
1830 gas_assert ((opcode->format & M6811_OP_BITMASK) == 0);
1831 gas_assert (nb_operands == 1);
1832 gas_assert (operands[0].reg1 == REG_NONE && operands[0].reg2 == REG_NONE);
1834 code = opcode->opcode;
1836 n = operands[0].exp.X_add_number;
1838 /* Turn into a long branch:
1839 - when force long branch option (and not for jbcc pseudos),
1840 - when jbcc and the constant is out of -128..127 range,
1841 - when branch optimization is allowed and branch out of range. */
1842 if ((jmp_mode == 0 && flag_force_long_jumps)
1843 || (operands[0].exp.X_op == O_constant
1844 && (!check_range (n, opcode->format) &&
1845 (jmp_mode == 1 || flag_fixed_branches == 0))))
1847 fix_new (frag_now, frag_now_fix (), 0,
1848 &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
1850 if (code == M6811_BSR || code == M6811_BRA || code == M6812_BSR)
1852 code = convert_branch (code);
1854 f = m68hc11_new_insn (1);
1855 number_to_chars_bigendian (f, code, 1);
1857 else if (current_architecture & cpu6812)
1859 /* 68HC12: translate the bcc into a lbcc. */
1860 f = m68hc11_new_insn (2);
1861 number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1);
1862 number_to_chars_bigendian (f + 1, code, 1);
1863 fixup16 (&operands[0].exp, M6812_OP_JUMP_REL16,
1864 M6812_OP_JUMP_REL16);
1865 return;
1867 else
1869 /* 68HC11: translate the bcc into b!cc +3; jmp <L>. */
1870 f = m68hc11_new_insn (3);
1871 code ^= 1;
1872 number_to_chars_bigendian (f, code, 1);
1873 number_to_chars_bigendian (f + 1, 3, 1);
1874 number_to_chars_bigendian (f + 2, M6811_JMP, 1);
1876 fixup16 (&operands[0].exp, M6811_OP_IND16, M6811_OP_IND16);
1877 return;
1880 /* Branch with a constant that must fit in 8-bits. */
1881 if (operands[0].exp.X_op == O_constant)
1883 if (!check_range (n, opcode->format))
1885 as_bad (_("Operand out of range for a relative branch: `%ld'"),
1888 else if (opcode->format & M6812_OP_JUMP_REL16)
1890 f = m68hc11_new_insn (4);
1891 number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1);
1892 number_to_chars_bigendian (f + 1, code, 1);
1893 number_to_chars_bigendian (f + 2, n & 0x0ffff, 2);
1895 else
1897 f = m68hc11_new_insn (2);
1898 number_to_chars_bigendian (f, code, 1);
1899 number_to_chars_bigendian (f + 1, n & 0x0FF, 1);
1902 else if (opcode->format & M6812_OP_JUMP_REL16)
1904 fix_new (frag_now, frag_now_fix (), 0,
1905 &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
1907 f = m68hc11_new_insn (2);
1908 number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1);
1909 number_to_chars_bigendian (f + 1, code, 1);
1910 fixup16 (&operands[0].exp, M6812_OP_JUMP_REL16, M6812_OP_JUMP_REL16);
1912 else
1914 char *op;
1916 fix_new (frag_now, frag_now_fix (), 0,
1917 &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
1919 /* Branch offset must fit in 8-bits, don't do some relax. */
1920 if (jmp_mode == 0 && flag_fixed_branches)
1922 op = m68hc11_new_insn (1);
1923 number_to_chars_bigendian (op, code, 1);
1924 fixup8 (&operands[0].exp, M6811_OP_JUMP_REL, M6811_OP_JUMP_REL);
1927 /* bra/bsr made be changed into jmp/jsr. */
1928 else if (code == M6811_BSR || code == M6811_BRA || code == M6812_BSR)
1930 /* Allocate worst case storage. */
1931 op = m68hc11_new_insn (3);
1932 number_to_chars_bigendian (op, code, 1);
1933 number_to_chars_bigendian (op + 1, 0, 1);
1934 frag_variant (rs_machine_dependent, 1, 1,
1935 ENCODE_RELAX (STATE_PC_RELATIVE, STATE_UNDF),
1936 operands[0].exp.X_add_symbol, (offsetT) n,
1937 op);
1939 else if (current_architecture & cpu6812)
1941 op = m68hc11_new_insn (2);
1942 number_to_chars_bigendian (op, code, 1);
1943 number_to_chars_bigendian (op + 1, 0, 1);
1944 frag_var (rs_machine_dependent, 2, 2,
1945 ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_UNDF),
1946 operands[0].exp.X_add_symbol, (offsetT) n, op);
1948 else
1950 op = m68hc11_new_insn (2);
1951 number_to_chars_bigendian (op, code, 1);
1952 number_to_chars_bigendian (op + 1, 0, 1);
1953 frag_var (rs_machine_dependent, 3, 3,
1954 ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_UNDF),
1955 operands[0].exp.X_add_symbol, (offsetT) n, op);
1960 /* Builds a dbne/dbeq/tbne/tbeq instruction. */
1961 static void
1962 build_dbranch_insn (struct m68hc11_opcode *opcode, operand operands[],
1963 int nb_operands, int jmp_mode)
1965 unsigned char code;
1966 char *f;
1967 unsigned long n;
1969 /* The relative branch conversion is not supported for
1970 brclr and brset. */
1971 gas_assert ((opcode->format & M6811_OP_BITMASK) == 0);
1972 gas_assert (nb_operands == 2);
1973 gas_assert (operands[0].reg1 != REG_NONE);
1975 code = opcode->opcode & 0x0FF;
1977 f = m68hc11_new_insn (1);
1978 number_to_chars_bigendian (f, code, 1);
1980 n = operands[1].exp.X_add_number;
1981 code = operands[0].reg1;
1983 if (operands[0].reg1 == REG_NONE || operands[0].reg1 == REG_CCR
1984 || operands[0].reg1 == REG_PC)
1985 as_bad (_("Invalid register for dbcc/tbcc instruction."));
1987 if (opcode->format & M6812_OP_IBCC_MARKER)
1988 code |= 0x80;
1989 else if (opcode->format & M6812_OP_TBCC_MARKER)
1990 code |= 0x40;
1992 if (!(opcode->format & M6812_OP_EQ_MARKER))
1993 code |= 0x20;
1995 /* Turn into a long branch:
1996 - when force long branch option (and not for jbcc pseudos),
1997 - when jdbcc and the constant is out of -256..255 range,
1998 - when branch optimization is allowed and branch out of range. */
1999 if ((jmp_mode == 0 && flag_force_long_jumps)
2000 || (operands[1].exp.X_op == O_constant
2001 && (!check_range (n, M6812_OP_IBCC_MARKER) &&
2002 (jmp_mode == 1 || flag_fixed_branches == 0))))
2004 f = frag_more (2);
2005 code ^= 0x20;
2006 number_to_chars_bigendian (f, code, 1);
2007 number_to_chars_bigendian (f + 1, M6812_JMP, 1);
2008 fixup16 (&operands[0].exp, M6811_OP_IND16, M6811_OP_IND16);
2009 return;
2012 /* Branch with a constant that must fit in 9-bits. */
2013 if (operands[1].exp.X_op == O_constant)
2015 if (!check_range (n, M6812_OP_IBCC_MARKER))
2017 as_bad (_("Operand out of range for a relative branch: `%ld'"),
2020 else
2022 if ((long) n < 0)
2023 code |= 0x10;
2025 f = frag_more (2);
2026 number_to_chars_bigendian (f, code, 1);
2027 number_to_chars_bigendian (f + 1, n & 0x0FF, 1);
2030 else
2032 /* Branch offset must fit in 8-bits, don't do some relax. */
2033 if (jmp_mode == 0 && flag_fixed_branches)
2035 fixup8 (&operands[0].exp, M6811_OP_JUMP_REL, M6811_OP_JUMP_REL);
2038 else
2040 f = frag_more (2);
2041 number_to_chars_bigendian (f, code, 1);
2042 number_to_chars_bigendian (f + 1, 0, 1);
2043 frag_var (rs_machine_dependent, 3, 3,
2044 ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_UNDF),
2045 operands[1].exp.X_add_symbol, (offsetT) n, f);
2050 #define OP_EXTENDED (M6811_OP_PAGE2 | M6811_OP_PAGE3 | M6811_OP_PAGE4)
2052 /* Assemble the post index byte for 68HC12 extended addressing modes. */
2054 static int
2055 build_indexed_byte (operand *op, int format ATTRIBUTE_UNUSED, int move_insn)
2057 unsigned char byte = 0;
2058 char *f;
2059 int mode;
2060 long val;
2062 val = op->exp.X_add_number;
2063 mode = op->mode;
2064 if (mode & M6812_AUTO_INC_DEC)
2066 byte = 0x20;
2067 if (mode & (M6812_POST_INC | M6812_POST_DEC))
2068 byte |= 0x10;
2070 if (op->exp.X_op == O_constant)
2072 if (!check_range (val, mode))
2073 as_bad (_("Increment/decrement value is out of range: `%ld'."),
2074 val);
2076 if (mode & (M6812_POST_INC | M6812_PRE_INC))
2077 byte |= (val - 1) & 0x07;
2078 else
2079 byte |= (8 - ((val) & 7)) | 0x8;
2082 switch (op->reg1)
2084 case REG_NONE:
2085 as_fatal (_("Expecting a register."));
2087 case REG_X:
2088 byte |= 0;
2089 break;
2091 case REG_Y:
2092 byte |= 0x40;
2093 break;
2095 case REG_SP:
2096 byte |= 0x80;
2097 break;
2099 default:
2100 as_bad (_("Invalid register for post/pre increment."));
2101 break;
2104 f = frag_more (1);
2105 number_to_chars_bigendian (f, byte, 1);
2106 return 1;
2109 if (mode & (M6812_OP_IDX | M6812_OP_D_IDX_2))
2111 switch (op->reg1)
2113 case REG_X:
2114 byte = 0;
2115 break;
2117 case REG_Y:
2118 byte = 1;
2119 break;
2121 case REG_SP:
2122 byte = 2;
2123 break;
2125 case REG_PC:
2126 byte = 3;
2127 break;
2129 default:
2130 as_bad (_("Invalid register."));
2131 break;
2134 if (op->exp.X_op == O_constant)
2136 if (!check_range (val, M6812_OP_IDX))
2137 as_bad (_("Offset out of 16-bit range: %ld."), val);
2139 if (move_insn && !(val >= -16 && val <= 15)
2140 && ((!(mode & M6812_OP_IDX) && !(mode & M6812_OP_D_IDX_2))
2141 || !(current_architecture & cpu9s12x)))
2143 as_bad (_("Offset out of 5-bit range for movw/movb insn: %ld."),
2144 val);
2145 return -1;
2148 if (val >= -16 && val <= 15 && !(mode & M6812_OP_D_IDX_2))
2150 byte = byte << 6;
2151 byte |= val & 0x1f;
2152 f = frag_more (1);
2153 number_to_chars_bigendian (f, byte, 1);
2154 return 1;
2156 else if (val >= -256 && val <= 255 && !(mode & M6812_OP_D_IDX_2))
2158 byte = byte << 3;
2159 byte |= 0xe0;
2160 if (val < 0)
2161 byte |= 0x1;
2162 f = frag_more (2);
2163 number_to_chars_bigendian (f, byte, 1);
2164 number_to_chars_bigendian (f + 1, val & 0x0FF, 1);
2165 return 2;
2167 else
2169 byte = byte << 3;
2170 if (mode & M6812_OP_D_IDX_2)
2171 byte |= 0xe3;
2172 else
2173 byte |= 0xe2;
2175 f = frag_more (3);
2176 number_to_chars_bigendian (f, byte, 1);
2177 number_to_chars_bigendian (f + 1, val & 0x0FFFF, 2);
2178 return 3;
2182 if (mode & M6812_OP_D_IDX_2)
2184 byte = (byte << 3) | 0xe3;
2185 f = frag_more (1);
2186 number_to_chars_bigendian (f, byte, 1);
2188 fixup16 (&op->exp, 0, 0);
2190 else if (op->reg1 != REG_PC)
2192 symbolS *sym;
2193 offsetT off;
2195 f = frag_more (1);
2196 number_to_chars_bigendian (f, byte, 1);
2197 sym = op->exp.X_add_symbol;
2198 off = op->exp.X_add_number;
2199 if (op->exp.X_op != O_symbol)
2201 sym = make_expr_symbol (&op->exp);
2202 off = 0;
2205 /* movb/movw cannot be relaxed. */
2206 if (move_insn)
2208 if ((mode & M6812_OP_IDX) && (current_architecture & cpu9s12x))
2210 /* Must treat as a 16bit relocate as size of final result is unknown. */
2212 byte <<= 3;
2213 byte |= 0xe2;
2214 number_to_chars_bigendian (f, byte, 1);
2215 f = frag_more (2);
2216 fix_new (frag_now, f - frag_now->fr_literal, 2,
2217 sym, off, 0, BFD_RELOC_M68HC12_16B);
2218 return 1;
2220 else
2222 /* Non-S12X will fail at relocate stage if offset out of range. */
2223 byte <<= 6;
2224 number_to_chars_bigendian (f, byte, 1);
2225 fix_new (frag_now, f - frag_now->fr_literal, 1,
2226 sym, off, 0, BFD_RELOC_M68HC12_5B);
2227 return 1;
2230 else
2232 number_to_chars_bigendian (f, byte, 1);
2233 frag_var (rs_machine_dependent, 2, 2,
2234 ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_UNDF),
2235 sym, off, f);
2238 else
2240 f = frag_more (1);
2242 /* movb/movw cannot be relaxed. */
2243 if (move_insn)
2245 byte <<= 6;
2246 number_to_chars_bigendian (f, byte, 1);
2247 fix_new (frag_now, f - frag_now->fr_literal, 1,
2248 op->exp.X_add_symbol, op->exp.X_add_number, 0, BFD_RELOC_M68HC12_5B);
2249 return 1;
2251 else
2253 number_to_chars_bigendian (f, byte, 1);
2254 frag_var (rs_machine_dependent, 2, 2,
2255 ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_UNDF),
2256 op->exp.X_add_symbol,
2257 op->exp.X_add_number, f);
2260 return 3;
2263 if (mode & (M6812_OP_REG | M6812_OP_D_IDX))
2265 if (mode & M6812_OP_D_IDX)
2267 if (op->reg1 != REG_D)
2268 as_bad (_("Expecting register D for indexed indirect mode."));
2269 if ((move_insn) && (!(current_architecture & cpu9s12x)))
2270 as_bad (_("Indexed indirect mode is not allowed for movb/movw."));
2272 byte = 0xE7;
2274 else
2276 switch (op->reg1)
2278 case REG_A:
2279 byte = 0xE4;
2280 break;
2282 case REG_B:
2283 byte = 0xE5;
2284 break;
2286 default:
2287 as_bad (_("Invalid accumulator register."));
2288 /* Fall through. */
2290 case REG_D:
2291 byte = 0xE6;
2292 break;
2295 switch (op->reg2)
2297 case REG_X:
2298 break;
2300 case REG_Y:
2301 byte |= (1 << 3);
2302 break;
2304 case REG_SP:
2305 byte |= (2 << 3);
2306 break;
2308 case REG_PC:
2309 byte |= (3 << 3);
2310 break;
2312 default:
2313 as_bad (_("Invalid indexed register."));
2314 break;
2316 f = frag_more (1);
2317 number_to_chars_bigendian (f, byte, 1);
2318 return 1;
2321 fprintf (stderr, "mode = 0x%x\nop->reg1 = 0x%x\nop->reg2 = 0x%x\n",
2322 mode, op->reg1, op->reg2);
2323 as_fatal (_("Addressing mode not implemented yet."));
2324 return 0;
2327 /* Assemble the 68HC12 register mode byte. */
2328 static int
2329 build_reg_mode (operand *op, int format)
2331 unsigned char byte;
2332 char *f;
2334 if ((format & M6812_OP_SEX_MARKER)
2335 && (op->reg1 != REG_A) && (op->reg1 != REG_B) && (op->reg1 != REG_CCR)
2336 && (!(current_architecture & cpu9s12x)))
2337 as_bad (_("Invalid source register for this instruction, use 'tfr'."));
2338 else if (op->reg1 == REG_NONE || op->reg1 == REG_PC)
2339 as_bad (_("Invalid source register."));
2341 if (format & M6812_OP_SEX_MARKER
2342 && op->reg2 != REG_D
2343 && op->reg2 != REG_X && op->reg2 != REG_Y && op->reg2 != REG_SP)
2344 as_bad (_("Invalid destination register for this instruction, use 'tfr'."));
2345 else if (op->reg2 == REG_NONE || op->reg2 == REG_PC)
2346 as_bad (_("Invalid destination register."));
2348 byte = (op->reg1 << 4) | (op->reg2);
2349 if (format & M6812_OP_EXG_MARKER)
2350 byte |= 0x80;
2352 if ((format & M6812_OP_SEX_MARKER)
2353 && (op->reg1 == REG_D) && (current_architecture & cpu9s12x))
2354 byte |= 0x08;
2356 f = frag_more (1);
2357 number_to_chars_bigendian (f, byte, 1);
2358 return 1;
2361 /* build_insn_xg takes a pointer to the opcode entry in the opcode table,
2362 the array of operand expressions and builds the corresponding instruction. */
2364 static void
2365 build_insn_xg (struct m68hc11_opcode *opcode,
2366 operand operands[],
2367 int nb_operands ATTRIBUTE_UNUSED)
2369 char *f;
2370 long format;
2372 /* Put the page code instruction if there is one. */
2373 format = opcode->format;
2375 if (!(operands[0].mode & (M6811_OP_LOW_ADDR | M6811_OP_HIGH_ADDR)))
2376 /* Need to retain those two modes, but clear for others. */
2377 operands[0].mode = 0;
2379 if (format & M68XG_OP_R_IMM8)
2381 /* These opcodes are byte followed by imm8. */
2382 f = m68hc11_new_insn (1);
2383 number_to_chars_bigendian (f, opcode->opcode >> 8, 1);
2384 fixup8_xg (&operands[0].exp, format, operands[0].mode);
2386 else if (format & M68XG_OP_R_IMM16)
2388 fixS *fixp;
2389 /* These opcodes expand into two imm8 instructions.
2390 Emit as low:high as per the Freescale datasheet.
2391 The linker requires them to be adjacent to handle the upper byte. */
2393 /* Build low byte. */
2394 f = m68hc11_new_insn (1);
2395 number_to_chars_bigendian (f, opcode->opcode >> 8, 1);
2396 operands[0].mode = M6811_OP_LOW_ADDR;
2397 f = frag_more (1);
2398 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
2399 &operands[0].exp, false, BFD_RELOC_M68HC12_LO8XG);
2400 fixp->fx_no_overflow = 1;
2401 number_to_chars_bigendian (f, 0, 1);
2403 /* Build high byte. */
2404 f = m68hc11_new_insn (1);
2405 number_to_chars_bigendian (f, (opcode->opcode >> 8) | 0x08, 1);
2406 operands[0].mode = M6811_OP_HIGH_ADDR;
2407 f = frag_more (1);
2408 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
2409 &operands[0].exp, false, BFD_RELOC_M68HC12_HI8XG);
2410 fixp->fx_no_overflow = 1;
2411 number_to_chars_bigendian (f, 0, 1);
2414 else if (format & M68XG_OP_REL9)
2416 f = m68hc11_new_insn (1);
2417 number_to_chars_bigendian (f, opcode->opcode >> 8, 1); /* High byte. */
2418 fixup8_xg (&operands[0].exp, format, M68XG_OP_REL9);
2420 else if (format & M68XG_OP_REL10)
2422 f = m68hc11_new_insn (1);
2423 number_to_chars_bigendian (f, opcode->opcode >> 8, 1); /* High byte. */
2424 fixup8_xg (&operands[0].exp, format, M68XG_OP_REL10);
2426 else
2428 f = m68hc11_new_insn (2);
2429 number_to_chars_bigendian (f, opcode->opcode, 2);
2431 return;
2434 /* build_insn takes a pointer to the opcode entry in the opcode table,
2435 the array of operand expressions and builds the corresponding instruction.
2436 This operation only deals with non relative jumps insn (need special
2437 handling). */
2439 static void
2440 build_insn (struct m68hc11_opcode *opcode,
2441 operand operands[],
2442 int nb_operands ATTRIBUTE_UNUSED)
2444 int i;
2445 char *f;
2446 long format;
2447 int move_insn = 0;
2449 /* Put the page code instruction if there is one. */
2450 format = opcode->format;
2452 if (format & M6811_OP_BRANCH)
2453 fix_new (frag_now, frag_now_fix (), 0,
2454 &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
2456 if (format & OP_EXTENDED)
2458 int page_code;
2460 f = m68hc11_new_insn (2);
2461 if (format & M6811_OP_PAGE2)
2462 page_code = M6811_OPCODE_PAGE2;
2463 else if (format & M6811_OP_PAGE3)
2464 page_code = M6811_OPCODE_PAGE3;
2465 else
2466 page_code = M6811_OPCODE_PAGE4;
2468 number_to_chars_bigendian (f, page_code, 1);
2469 f++;
2471 else
2472 f = m68hc11_new_insn (1);
2474 number_to_chars_bigendian (f, opcode->opcode, 1);
2476 i = 0;
2478 /* The 68HC12 movb and movw instructions are special. We have to handle
2479 them in a special way. */
2480 if (format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2))
2482 move_insn = 1;
2483 if (format & M6812_OP_IDX)
2485 build_indexed_byte (&operands[0], format, 1);
2486 i = 1;
2487 format &= ~M6812_OP_IDX;
2489 if (format & M6812_OP_IDX_P2)
2491 build_indexed_byte (&operands[1], format, 1);
2492 i = 0;
2493 format &= ~M6812_OP_IDX_P2;
2497 if (format & (M6811_OP_DIRECT | M6811_OP_IMM8))
2499 fixup8 (&operands[i].exp,
2500 format & (M6811_OP_DIRECT | M6811_OP_IMM8 | M6812_OP_TRAP_ID),
2501 operands[i].mode);
2502 i++;
2504 else if (IS_CALL_SYMBOL (format) && nb_operands == 1)
2506 format &= ~M6812_OP_PAGE;
2507 fixup24 (&operands[i].exp, format & M6811_OP_IND16,
2508 operands[i].mode);
2509 i++;
2511 else if (format & (M6811_OP_IMM16 | M6811_OP_IND16))
2513 fixup16 (&operands[i].exp,
2514 format & (M6811_OP_IMM16 | M6811_OP_IND16 | M6812_OP_PAGE),
2515 operands[i].mode);
2516 i++;
2518 else if (format & (M6811_OP_IX | M6811_OP_IY))
2520 if ((format & M6811_OP_IX) && (operands[0].reg1 != REG_X))
2521 as_bad (_("Invalid indexed register, expecting register X."));
2522 if ((format & M6811_OP_IY) && (operands[0].reg1 != REG_Y))
2523 as_bad (_("Invalid indexed register, expecting register Y."));
2525 fixup8 (&operands[0].exp, M6811_OP_IX, operands[0].mode);
2526 i = 1;
2528 else if (format &
2529 (M6812_OP_IDX | M6812_OP_IDX_2 | M6812_OP_IDX_1
2530 | M6812_OP_D_IDX | M6812_OP_D_IDX_2))
2532 build_indexed_byte (&operands[i], format, move_insn);
2533 i++;
2535 else if (format & M6812_OP_REG && current_architecture & cpu6812)
2537 build_reg_mode (&operands[i], format);
2538 i++;
2540 if (format & M6811_OP_BITMASK)
2542 fixup8 (&operands[i].exp, M6811_OP_BITMASK, operands[i].mode);
2543 i++;
2545 if (format & M6811_OP_JUMP_REL)
2547 fixup8 (&operands[i].exp, M6811_OP_JUMP_REL, operands[i].mode);
2549 else if (format & M6812_OP_IND16_P2)
2551 fixup16 (&operands[1].exp, M6811_OP_IND16, operands[1].mode);
2553 if (format & M6812_OP_PAGE)
2555 fixup8 (&operands[i].exp, M6812_OP_PAGE, operands[i].mode);
2559 /* Opcode identification and operand analysis. */
2561 /* find() gets a pointer to an entry in the opcode table. It must look at all
2562 opcodes with the same name and use the operands to choose the correct
2563 opcode. Returns the opcode pointer if there was a match and 0 if none. */
2564 static struct m68hc11_opcode *
2565 find (struct m68hc11_opcode_def *opc, operand operands[], int nb_operands)
2567 int i, match, pos;
2568 struct m68hc11_opcode *opcode;
2569 struct m68hc11_opcode *op_indirect;
2571 op_indirect = 0;
2572 opcode = opc->opcode;
2574 /* Now search the opcode table table for one with operands
2575 that matches what we've got. */
2577 if (current_architecture & cpuxgate)
2579 /* Many XGATE insns are simple enough that we get an exact match. */
2580 for (pos = match = 0; match == 0 && pos < opc->nb_modes; pos++, opcode++)
2581 if (opcode->format == operands[nb_operands-1].mode)
2582 return opcode;
2584 return 0;
2587 /* Non XGATE */
2589 /* Now search the opcode table table for one with operands
2590 that matches what we've got. We're only done if the operands matched so
2591 far AND there are no more to check. */
2592 for (pos = match = 0; match == 0 && pos < opc->nb_modes; pos++, opcode++)
2594 int poss_indirect = 0;
2595 long format = opcode->format;
2596 int expect;
2598 expect = 0;
2599 if (opcode->format & M6811_OP_MASK)
2600 expect++;
2601 if (opcode->format & M6811_OP_BITMASK)
2602 expect++;
2603 if (opcode->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
2604 expect++;
2605 if (opcode->format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2))
2606 expect++;
2607 if ((opcode->format & M6812_OP_PAGE)
2608 && (!IS_CALL_SYMBOL (opcode->format) || nb_operands == 2))
2609 expect++;
2611 for (i = 0; expect == nb_operands && i < nb_operands; i++)
2613 int mode = operands[i].mode;
2615 if (mode & M6811_OP_IMM16)
2617 if (format &
2618 (M6811_OP_IMM8 | M6811_OP_IMM16 | M6811_OP_BITMASK))
2619 continue;
2620 break;
2622 if (mode == M6811_OP_DIRECT)
2624 if (format & M6811_OP_DIRECT)
2625 continue;
2627 /* If the operand is a page 0 operand, remember a
2628 possible <abs-16> addressing mode. We mark
2629 this and continue to check other operands. */
2630 if (format & M6811_OP_IND16
2631 && flag_strict_direct_addressing && op_indirect == 0)
2633 poss_indirect = 1;
2634 continue;
2636 break;
2638 if (mode & M6811_OP_IND16)
2640 if (i == 0 && (format & M6811_OP_IND16) != 0)
2641 continue;
2642 if (i != 0 && (format & M6812_OP_PAGE) != 0)
2643 continue;
2644 if (i != 0 && (format & M6812_OP_IND16_P2) != 0)
2645 continue;
2646 if (i == 0 && (format & M6811_OP_BITMASK))
2647 break;
2649 if (mode & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
2651 if (format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
2652 continue;
2654 if (mode & M6812_OP_REG)
2656 if (i == 0
2657 && (format & M6812_OP_REG)
2658 && (operands[i].reg2 == REG_NONE))
2659 continue;
2660 if (i == 0
2661 && (format & M6812_OP_REG)
2662 && (format & M6812_OP_REG_2)
2663 && (operands[i].reg2 != REG_NONE))
2664 continue;
2665 if (i == 0
2666 && (format & M6812_OP_IDX)
2667 && (operands[i].reg2 != REG_NONE))
2668 continue;
2669 if (i == 0
2670 && (format & M6812_OP_IDX)
2671 && (format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2)))
2672 continue;
2673 if (i == 1
2674 && (format & M6812_OP_IDX_P2))
2675 continue;
2676 break;
2678 if (mode & M6812_OP_IDX)
2680 if (format & M6811_OP_IX && operands[i].reg1 == REG_X)
2681 continue;
2682 if (format & M6811_OP_IY && operands[i].reg1 == REG_Y)
2683 continue;
2684 if (i == 0
2685 && format & (M6812_OP_IDX | M6812_OP_IDX_1 | M6812_OP_IDX_2)
2686 && (operands[i].reg1 == REG_X
2687 || operands[i].reg1 == REG_Y
2688 || operands[i].reg1 == REG_SP
2689 || operands[i].reg1 == REG_PC))
2690 continue;
2691 if (i == 1 && (format & M6812_OP_IDX_P2))
2692 continue;
2694 if (mode & format & (M6812_OP_D_IDX | M6812_OP_D_IDX_2))
2696 if (i == 0)
2697 continue;
2699 if (mode & M6812_AUTO_INC_DEC)
2701 if (i == 0
2702 && format & (M6812_OP_IDX | M6812_OP_IDX_1 |
2703 M6812_OP_IDX_2))
2704 continue;
2705 if (i == 1 && format & M6812_OP_IDX_P2)
2706 continue;
2708 break;
2710 match = i == nb_operands;
2712 /* Operands are ok but an operand uses page 0 addressing mode
2713 while the insn supports abs-16 mode. Keep a reference to this
2714 insns in case there is no insn supporting page 0 addressing. */
2715 if (match && poss_indirect)
2717 op_indirect = opcode;
2718 match = 0;
2720 if (match)
2721 break;
2724 /* Page 0 addressing is used but not supported by any insn.
2725 If absolute addresses are supported, we use that insn. */
2726 if (match == 0 && op_indirect)
2728 opcode = op_indirect;
2729 match = 1;
2732 return match ? opcode : 0;
2735 /* Find the real opcode and its associated operands. We use a progressive
2736 approach here. On entry, 'opc' points to the first opcode in the
2737 table that matches the opcode name in the source line. We try to
2738 isolate an operand, find a possible match in the opcode table.
2739 We isolate another operand if no match were found. The table 'operands'
2740 is filled while operands are recognized.
2742 Returns the opcode pointer that matches the opcode name in the
2743 source line and the associated operands. */
2744 static struct m68hc11_opcode *
2745 find_opcode (struct m68hc11_opcode_def *opc, operand operands[],
2746 int *nb_operands)
2748 struct m68hc11_opcode *opcode;
2749 int i;
2751 if (opc->max_operands == 0)
2753 *nb_operands = 0;
2754 return opc->opcode;
2757 for (i = 0; i < opc->max_operands;)
2759 int result;
2761 result = get_operand (&operands[i], i, opc->format);
2762 if (result <= 0)
2763 return 0;
2765 /* Special case where the bitmask of the bclr/brclr
2766 instructions is not introduced by #.
2767 Example: bclr 3,x $80. */
2768 if (i == 1 && (opc->format & M6811_OP_BITMASK)
2769 && (operands[i].mode & M6811_OP_IND16))
2771 operands[i].mode = M6811_OP_IMM16;
2774 i += result;
2775 *nb_operands = i;
2776 if (i >= opc->min_operands)
2778 opcode = find (opc, operands, i);
2780 /* Another special case for 'call foo,page' instructions.
2781 Since we support 'call foo' and 'call foo,page' we must look
2782 if the optional page specification is present otherwise we will
2783 assemble immediately and treat the page spec as garbage. */
2784 if (opcode && !(opcode->format & M6812_OP_PAGE))
2785 return opcode;
2787 if (opcode && *input_line_pointer != ',')
2788 return opcode;
2791 if (*input_line_pointer == ',')
2792 input_line_pointer++;
2795 return 0;
2798 #define M6812_XBCC_MARKER (M6812_OP_TBCC_MARKER \
2799 | M6812_OP_DBCC_MARKER \
2800 | M6812_OP_IBCC_MARKER)
2802 /* Gas line assembler entry point. */
2804 /* This is the main entry point for the machine-dependent assembler. str
2805 points to a machine-dependent instruction. This function is supposed to
2806 emit the frags/bytes it assembles to. */
2807 void
2808 md_assemble (char *str)
2810 struct m68hc11_opcode_def *opc;
2811 struct m68hc11_opcode *opcode;
2813 struct m68hc11_opcode opcode_local;
2814 unsigned char *op_start, *op_end;
2815 char *save;
2816 char name[20];
2817 int nlen = 0;
2818 operand operands[M6811_MAX_OPERANDS];
2819 int nb_operands = 0;
2820 int branch_optimize = 0;
2821 int alias_id = -1;
2823 /* Drop leading whitespace. */
2824 while (*str == ' ')
2825 str++;
2827 /* Find the opcode end and get the opcode in 'name'. The opcode is forced
2828 lower case (the opcode table only has lower case op-codes). */
2829 for (op_start = op_end = (unsigned char *) str;
2830 *op_end && !is_end_of_line[*op_end] && *op_end != ' ';
2831 op_end++)
2833 name[nlen] = TOLOWER (op_start[nlen]);
2834 nlen++;
2835 if (nlen == sizeof (name) - 1)
2836 break;
2838 name[nlen] = 0;
2840 if (nlen == 0)
2842 as_bad (_("No instruction or missing opcode."));
2843 return;
2846 if (current_architecture == cpuxgate)
2848 /* Find the opcode definition given its name. */
2849 opc = (struct m68hc11_opcode_def *) str_hash_find (m68hc11_hash, name);
2850 if (opc == NULL)
2852 as_bad (_("Opcode `%s' is not recognized."), name);
2853 return;
2856 /* Grab a local copy. */
2857 opcode_local.name = opc->opcode->name;
2858 /* These will be incomplete where multiple variants exist. */
2859 opcode_local.opcode = opc->opcode->opcode;
2860 opcode_local.format = opc->opcode->format;
2862 save = input_line_pointer;
2863 input_line_pointer = (char *) op_end;
2865 if (opc->format == M68XG_OP_NONE)
2867 /* No special handling required. */
2868 opcode_local.format = M68XG_OP_NONE;
2869 build_insn_xg (opc->opcode, operands, 0);
2870 return;
2873 /* Special handling of TFR. */
2874 if (startswith (opc->opcode->name, "tfr"))
2876 /* There must be two operands with a comma. */
2877 input_line_pointer = skip_whites (input_line_pointer);
2878 operands[0].reg1 = register_name ();
2879 if (operands[0].reg1 == REG_NONE)
2881 as_bad ("Invalid register\n");
2882 return;
2884 input_line_pointer = skip_whites (input_line_pointer);
2885 if (*input_line_pointer != ',')
2887 as_bad ("Missing comma.\n");
2888 return;
2890 input_line_pointer++;
2891 input_line_pointer = skip_whites (input_line_pointer);
2892 operands[1].reg1 = register_name ();
2893 if (operands[1].reg1 == REG_NONE)
2895 as_bad ("Invalid register\n");
2896 return;
2898 input_line_pointer = skip_whites (input_line_pointer);
2899 if (*input_line_pointer != '\n' && *input_line_pointer)
2901 as_bad (_("Garbage at end of instruction: `%s'."),
2902 input_line_pointer);
2903 return;
2905 if (operands[1].reg1 == REG_CCR) /* ,CCR */
2906 opc->opcode->opcode = 0x00f8 | ( operands[0].reg1 << 8);
2907 else if (operands[0].reg1 == REG_CCR) /* CCR, */
2908 opc->opcode->opcode = 0x00f9 | ( operands[1].reg1 << 8);
2909 else if (operands[1].reg1 == REG_PC) /* ,PC */
2910 opc->opcode->opcode = 0x00fa | ( operands[0].reg1 << 8);
2911 else
2913 as_bad ("Invalid operand to TFR\n");
2914 return;
2916 /* no special handling required */
2917 opcode_local.format = M68XG_OP_NONE;
2918 opcode_local.opcode = opc->opcode->opcode;
2919 build_insn_xg (&opcode_local, operands, 0);
2920 return;
2923 /* CSEM, SSEM */
2924 if (opc->format & M68XG_OP_IMM3)
2926 /* Either IMM3 or R */
2927 input_line_pointer = skip_whites (input_line_pointer);
2928 if ((*input_line_pointer == 'R') || (*input_line_pointer == 'r'))
2930 operands[0].reg1 = register_name ();
2931 if (operands[0].reg1 == REG_NONE)
2933 as_bad ("Invalid register\n");
2934 return;
2936 operands[0].mode = M68XG_OP_R;
2937 /* One opcode has multiple modes, so find right one. */
2938 opcode = find (opc, operands, 1);
2939 if (opcode)
2941 opcode_local.opcode = opcode->opcode
2942 | (operands[0].reg1 << 8);
2943 opcode_local.format = M68XG_OP_NONE;
2944 build_insn_xg (&opcode_local, operands, 1);
2946 else
2947 as_bad ("No opcode found\n");
2949 return;
2951 else
2953 if (*input_line_pointer == '#')
2954 input_line_pointer++;
2956 expression (&operands[0].exp);
2957 if (operands[0].exp.X_op == O_illegal)
2959 as_bad (_("Illegal operand."));
2960 return;
2962 else if (operands[0].exp.X_op == O_absent)
2964 as_bad (_("Missing operand."));
2965 return;
2968 if (check_range (operands[0].exp.X_add_number,M68XG_OP_IMM3))
2970 opcode_local.opcode |= (operands[0].exp.X_add_number);
2971 operands[0].mode = M68XG_OP_IMM3;
2973 opcode = find (opc, operands, 1);
2974 if (opcode)
2976 opcode_local.opcode = opcode->opcode;
2977 opcode_local.opcode
2978 |= (operands[0].exp.X_add_number) << 8;
2979 opcode_local.format = M68XG_OP_NONE;
2980 build_insn_xg (&opcode_local, operands, 1);
2982 else
2983 as_bad ("No opcode found\n");
2985 return;
2987 else
2989 as_bad ("Number out of range for IMM3\n");
2990 return;
2995 /* Special handling of SIF. */
2996 if (startswith (opc->opcode->name, "sif"))
2998 /* Either OP_NONE or OP_RS. */
2999 if (*input_line_pointer != '\n')
3000 input_line_pointer = skip_whites (input_line_pointer);
3002 if ((*input_line_pointer == '\n') || (*input_line_pointer == '\r')
3003 || (*input_line_pointer == '\0'))
3004 opc->opcode->opcode = 0x0300;
3005 else
3007 operands[0].reg1 = register_name ();
3008 if (operands[0].reg1 == REG_NONE)
3010 as_bad ("Invalid register\n");
3011 return;
3013 opcode_local.opcode = 0x00f7 | (operands[0].reg1 << 8);
3015 opcode_local.format = M68XG_OP_NONE;
3016 build_insn_xg (&opcode_local, operands, 0);
3017 return;
3020 /* SEX, PAR, JAL plus aliases NEG, TST, COM */
3021 if (opc->format & M68XG_OP_R)
3023 input_line_pointer = skip_whites (input_line_pointer);
3024 operands[0].reg1 = register_name ();
3025 if (operands[0].reg1 == REG_NONE)
3027 as_bad ("Invalid register\n");
3028 return;
3030 if ((*input_line_pointer == '\n') || (*input_line_pointer == '\r')
3031 || (*input_line_pointer == '\0'))
3033 /* Likely to be OP R. */
3034 if (opc->format & M68XG_OP_R)
3036 operands[0].mode = M68XG_OP_R;
3038 opcode = find (opc, operands, 1);
3039 if (opcode)
3041 if ((startswith (opc->opcode->name, "com"))
3042 || (startswith (opc->opcode->name, "neg")))
3043 /* Special case for com RD as alias for sub RD,R0,RS */
3044 /* Special case for neg RD as alias for sub RD,R0,RS */
3045 opcode_local.opcode = opcode->opcode
3046 | (operands[0].reg1 << 8) | (operands[0].reg1 << 2);
3047 else if (startswith (opc->opcode->name, "tst"))
3048 /* Special case for tst RS alias for sub R0, RS, R0 */
3049 opcode_local.opcode = opcode->opcode
3050 | (operands[0].reg1 << 5);
3051 else
3052 opcode_local.opcode |= (operands[0].reg1 << 8);
3054 opcode_local.format = M68XG_OP_NONE;
3055 build_insn_xg (&opcode_local, operands, 0);
3057 else
3058 as_bad ("No valid mode found\n");
3060 return;
3064 if (opc->format & (M68XG_OP_REL9 | M68XG_OP_REL10))
3066 opcode_local.format = opc->format;
3067 input_line_pointer = skip_whites (input_line_pointer);
3068 expression (&operands[0].exp);
3069 if (operands[0].exp.X_op == O_illegal)
3071 as_bad (_("Illegal operand."));
3072 return;
3074 else if (operands[0].exp.X_op == O_absent)
3076 as_bad (_("Missing operand."));
3077 return;
3079 opcode_local.opcode = opc->opcode->opcode;
3080 build_insn_xg (&opcode_local, operands, 1);
3081 return;
3085 /* For other command formats, parse input line and determine the mode
3086 we are using as we go. */
3088 input_line_pointer = skip_whites (input_line_pointer);
3089 if ((*input_line_pointer == '\n') || (*input_line_pointer == '\r')
3090 || (*input_line_pointer == '\0'))
3091 return; /* nothing left */
3093 if (*input_line_pointer == '#')
3095 as_bad ("No register specified before hash\n");
3096 return;
3099 /* first operand is expected to be a register */
3100 if ((*input_line_pointer == 'R') || (*input_line_pointer == 'r'))
3102 operands[0].reg1 = register_name ();
3103 if (operands[0].reg1 == REG_NONE)
3105 as_bad ("Invalid register\n");
3106 return;
3110 input_line_pointer = skip_whites (input_line_pointer);
3111 if (*input_line_pointer != ',')
3113 as_bad ("Missing operand\n");
3114 return;
3116 input_line_pointer++;
3117 input_line_pointer = skip_whites (input_line_pointer);
3119 if (*input_line_pointer == '#')
3121 /* Some kind of immediate mode, check if this is possible. */
3122 if (!(opc->format
3123 & (M68XG_OP_R_IMM8 | M68XG_OP_R_IMM16 | M68XG_OP_R_IMM4)))
3124 as_bad ("Invalid immediate mode for `%s'", opc->opcode->name);
3125 else
3127 input_line_pointer++;
3128 input_line_pointer = skip_whites (input_line_pointer);
3129 if (startswith (input_line_pointer, "%hi"))
3131 input_line_pointer += 3;
3132 operands[0].mode = M6811_OP_HIGH_ADDR;
3134 else if (startswith (input_line_pointer, "%lo"))
3136 input_line_pointer += 3;
3137 operands[0].mode = M6811_OP_LOW_ADDR;
3139 else
3140 operands[0].mode = 0;
3142 expression (&operands[0].exp);
3143 if (operands[0].exp.X_op == O_illegal)
3145 as_bad (_("Illegal operand."));
3146 return;
3148 else if (operands[0].exp.X_op == O_absent)
3150 as_bad (_("Missing operand."));
3151 return;
3153 /* ok so far, can only be one mode */
3154 opcode_local.format = opc->format
3155 & (M68XG_OP_R_IMM8 | M68XG_OP_R_IMM16 | M68XG_OP_R_IMM4);
3156 if (opcode_local.format & M68XG_OP_R_IMM4)
3158 operands[0].mode = M68XG_OP_R_IMM4;
3159 /* same opcodes have multiple modes, so find right one */
3160 opcode = find (opc, operands, 1);
3161 if (opcode)
3162 opcode_local.opcode = opcode->opcode
3163 | (operands[0].reg1 << 8);
3165 if (operands[0].exp.X_op != O_constant)
3166 as_bad ("Only constants supported at for IMM4 mode\n");
3167 else
3169 if (check_range
3170 (operands[0].exp.X_add_number,M68XG_OP_R_IMM4))
3171 opcode_local.opcode
3172 |= (operands[0].exp.X_add_number << 4);
3173 else
3174 as_bad ("Number out of range for IMM4\n");
3176 opcode_local.format = M68XG_OP_NONE;
3178 else if (opcode_local.format & M68XG_OP_R_IMM16)
3180 operands[0].mode = M68XG_OP_R_IMM16;
3182 opcode = find (opc, operands, 1);
3183 if (opcode)
3185 opcode_local.opcode = opcode->opcode
3186 | (operands[0].reg1 << 8);
3189 else
3191 opcode_local.opcode = opc->opcode->opcode
3192 | (operands[0].reg1 << 8);
3194 build_insn_xg (&opcode_local, operands, 1);
3197 else if ((*input_line_pointer == 'R') || (*input_line_pointer == 'r'))
3199 /* we've got as far as OP R, R */
3200 operands[1].reg1 = register_name ();
3201 if (operands[1].reg1 == REG_NONE)
3203 as_bad ("Invalid register\n");
3204 return;
3206 if ((*input_line_pointer == '\n') || (*input_line_pointer == '\r')
3207 || (*input_line_pointer == '\0'))
3209 /* looks like OP_R_R */
3210 if (opc->format & M68XG_OP_R_R)
3212 operands[0].mode = M68XG_OP_R_R;
3213 /* same opcodes have multiple modes, so find right one */
3214 opcode = find (opc, operands, 1);
3215 if (opcode)
3217 if ((startswith (opc->opcode->name, "com"))
3218 || (startswith (opc->opcode->name, "mov"))
3219 || (startswith (opc->opcode->name, "neg")))
3221 /* Special cases for:
3222 com RD, RS alias for xnor RD,R0,RS
3223 mov RD, RS alias for or RD, R0, RS
3224 neg RD, RS alias for sub RD, R0, RS */
3225 opcode_local.opcode = opcode->opcode
3226 | (operands[0].reg1 << 8) | (operands[1].reg1 << 2);
3228 else if ((startswith (opc->opcode->name, "cmp"))
3229 || (startswith (opc->opcode->name, "cpc")))
3231 /* special cases for:
3232 cmp RS1, RS2 alias for sub R0, RS1, RS2
3233 cpc RS1, RS2 alias for sbc R0, RS1, RS2 */
3234 opcode_local.opcode = opcode->opcode
3235 | (operands[0].reg1 << 5) | (operands[1].reg1 << 2);
3237 else
3239 opcode_local.opcode = opcode->opcode
3240 | (operands[0].reg1 << 8) | (operands[1].reg1 << 5);
3242 opcode_local.format = M68XG_OP_NONE;
3243 build_insn_xg (&opcode_local, operands, 1);
3246 else
3248 as_bad ("No valid mode found\n");
3251 else
3253 /* more data */
3254 if (*input_line_pointer != ',')
3256 as_bad (_("Missing operand."));
3257 return;
3259 input_line_pointer++;
3260 input_line_pointer = skip_whites (input_line_pointer);
3261 if ((*input_line_pointer == 'R') || (*input_line_pointer == 'r'))
3263 operands[2].reg1 = register_name ();
3264 if (operands[2].reg1 == REG_NONE)
3266 as_bad ("Invalid register\n");
3267 return;
3269 if (opc->format & M68XG_OP_R_R_R)
3271 operands[0].mode = M68XG_OP_R_R_R;
3273 opcode = find (opc, operands, 1);
3274 if (opcode)
3276 opcode_local.opcode = opcode->opcode
3277 | (operands[0].reg1 << 8) | (operands[1].reg1 << 5)
3278 | (operands[2].reg1 << 2);
3279 opcode_local.format = M68XG_OP_NONE;
3280 build_insn_xg (&opcode_local, operands, 1);
3283 else
3285 as_bad ("No valid mode found\n");
3290 else if (*input_line_pointer == '(') /* Indexed modes */
3292 input_line_pointer++;
3293 input_line_pointer = skip_whites (input_line_pointer);
3294 if ((*input_line_pointer == 'R') || (*input_line_pointer == 'r'))
3296 /* we've got as far as OP R, (R */
3297 operands[1].reg1 = register_name ();
3298 if (operands[1].reg1 == REG_NONE)
3300 as_bad ("Invalid register\n");
3301 return;
3304 if ((*input_line_pointer == '\n') || (*input_line_pointer == '\r')
3305 || (*input_line_pointer == '\0'))
3307 /* Looks like OP_R_R. */
3308 as_bad (_("Missing operand."));
3309 return;
3312 input_line_pointer = skip_whites (input_line_pointer);
3314 if (*input_line_pointer != ',')
3316 as_bad (_("Missing operand."));
3317 return;
3319 input_line_pointer++;
3320 input_line_pointer = skip_whites (input_line_pointer);
3322 if (*input_line_pointer == '#')
3324 input_line_pointer++;
3325 input_line_pointer = skip_whites (input_line_pointer);
3326 expression (&operands[0].exp);
3327 if (operands[0].exp.X_op == O_illegal)
3329 as_bad (_("Illegal operand."));
3330 return;
3332 else if (operands[0].exp.X_op == O_absent)
3334 as_bad (_("Missing operand."));
3335 return;
3338 input_line_pointer = skip_whites (input_line_pointer);
3339 if (*input_line_pointer != ')')
3341 as_bad ("Missing `)' to close register indirect operand.");
3342 return;
3344 else
3346 input_line_pointer++;
3349 /* Ok so far, can only be one mode. */
3350 opcode_local.format = M68XG_OP_R_R_OFFS5;
3351 operands[0].mode = M68XG_OP_R_R_OFFS5;
3353 opcode = find (opc, operands, 1);
3354 if (opcode)
3356 opcode_local.opcode = opcode->opcode
3357 | (operands[0].reg1 << 8) | (operands[1].reg1 << 5);
3358 if (operands[0].exp.X_op != O_constant)
3360 as_bad
3361 ("Only constants supported for indexed OFFS5 mode\n");
3363 else
3365 if (check_range (operands[0].exp.X_add_number,
3366 M68XG_OP_R_R_OFFS5))
3368 opcode_local.opcode
3369 |= (operands[0].exp.X_add_number);
3370 opcode_local.format = M68XG_OP_NONE;
3371 build_insn_xg (&opcode_local, operands, 1);
3373 else
3375 as_bad ("Number out of range for OFFS5\n");
3380 else
3382 operands[0].mode = M68XG_OP_RD_RB_RI;
3384 if (*input_line_pointer == '-')
3386 operands[0].mode = M68XG_OP_RD_RB_mRI;
3387 input_line_pointer++;
3389 operands[2].reg1 = register_name ();
3390 if (operands[2].reg1 == REG_NONE)
3392 as_bad ("Invalid register\n");
3393 return;
3396 if (*input_line_pointer == '+')
3398 if (opcode_local.format == M68XG_OP_RD_RB_mRI)
3400 as_bad (_("Illegal operand."));
3401 return;
3403 operands[0].mode = M68XG_OP_RD_RB_RIp;
3404 input_line_pointer++;
3407 input_line_pointer = skip_whites (input_line_pointer);
3408 if (*input_line_pointer != ')')
3410 as_bad
3411 ("Missing `)' to close register indirect operand.");
3412 return;
3414 else
3416 input_line_pointer++;
3419 opcode = find (opc, operands, 1);
3420 if (opcode)
3422 opcode_local.opcode = opcode->opcode
3423 | (operands[0].reg1 << 8) | (operands[1].reg1 << 5)
3424 | (operands[2].reg1 << 2);
3425 opcode_local.format = M68XG_OP_NONE;
3426 build_insn_xg (&opcode_local, operands, 1);
3428 else
3430 as_bad ("Failed to find opcode for %s %s\n",
3431 opc->opcode->name, (char *)op_end);
3436 else
3438 as_bad (_("Failed to find a valid mode for `%s'."),
3439 opc->opcode->name);
3442 if (opc->opcode && !flag_mri)
3444 char *p = input_line_pointer;
3446 while (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r')
3447 p++;
3449 if (*p != '\n' && *p)
3450 as_bad (_("Garbage at end of instruction: `%s'."), p);
3453 input_line_pointer = save;
3455 /* Opcode is known but does not have valid operands. Print out the
3456 syntax for this opcode. */
3457 if (opc->opcode == 0)
3459 if (flag_print_insn_syntax)
3460 print_insn_format (name);
3462 as_bad (_("Invalid operand for `%s'"), name);
3463 return;
3466 return;
3469 /* Find the opcode definition given its name. */
3470 opc = (struct m68hc11_opcode_def *) str_hash_find (m68hc11_hash, name);
3472 /* If it's not recognized, look for 'jbsr' and 'jbxx'. These are
3473 pseudo insns for relative branch. For these branches, we always
3474 optimize them (turned into absolute branches) even if --short-branches
3475 is given. */
3476 if (opc == NULL && name[0] == 'j' && name[1] == 'b')
3478 opc = (struct m68hc11_opcode_def *) str_hash_find (m68hc11_hash,
3479 &name[1]);
3480 if (opc
3481 && (!(opc->format & M6811_OP_JUMP_REL)
3482 || (opc->format & M6811_OP_BITMASK)))
3483 opc = 0;
3484 if (opc)
3485 branch_optimize = 1;
3488 /* The following test should probably be removed. This does not conform
3489 to Motorola assembler specs. */
3490 if (opc == NULL && flag_mri)
3492 if (*op_end == ' ' || *op_end == '\t')
3494 while (*op_end == ' ' || *op_end == '\t')
3495 op_end++;
3497 if (nlen < 19
3498 && (*op_end &&
3499 (is_end_of_line[op_end[1]]
3500 || op_end[1] == ' ' || op_end[1] == '\t'
3501 || !ISALNUM (op_end[1])))
3502 && (*op_end == 'a' || *op_end == 'b'
3503 || *op_end == 'A' || *op_end == 'B'
3504 || *op_end == 'd' || *op_end == 'D'
3505 || *op_end == 'x' || *op_end == 'X'
3506 || *op_end == 'y' || *op_end == 'Y'))
3508 name[nlen++] = TOLOWER (*op_end++);
3509 name[nlen] = 0;
3510 opc = (struct m68hc11_opcode_def *) str_hash_find (m68hc11_hash,
3511 name);
3516 /* Identify a possible instruction alias. There are some on the
3517 68HC12 to emulate a few 68HC11 instructions. */
3518 if (opc == NULL && (current_architecture & cpu6812))
3520 int i;
3522 for (i = 0; i < m68hc12_num_alias; i++)
3523 if (strcmp (m68hc12_alias[i].name, name) == 0)
3525 alias_id = i;
3526 break;
3529 if (opc == NULL && alias_id < 0)
3531 as_bad (_("Opcode `%s' is not recognized."), name);
3532 return;
3534 save = input_line_pointer;
3535 input_line_pointer = (char *) op_end;
3537 if (opc)
3539 opc->used++;
3540 opcode = find_opcode (opc, operands, &nb_operands);
3542 else
3543 opcode = 0;
3545 if ((opcode || alias_id >= 0) && !flag_mri)
3547 char *p = input_line_pointer;
3549 while (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r')
3550 p++;
3552 if (*p != '\n' && *p)
3553 as_bad (_("Garbage at end of instruction: `%s'."), p);
3556 input_line_pointer = save;
3558 if (alias_id >= 0)
3560 char *f = m68hc11_new_insn (m68hc12_alias[alias_id].size);
3562 number_to_chars_bigendian (f, m68hc12_alias[alias_id].code1, 1);
3563 if (m68hc12_alias[alias_id].size > 1)
3564 number_to_chars_bigendian (f + 1, m68hc12_alias[alias_id].code2, 1);
3566 return;
3569 /* Opcode is known but does not have valid operands. Print out the
3570 syntax for this opcode. */
3571 if (opcode == 0)
3573 if (flag_print_insn_syntax)
3574 print_insn_format (name);
3576 if (((strcmp (name, "movb") == 0) || (strcmp (name, "movw") == 0))
3577 && (current_architecture & cpu9s12x))
3579 char *f;
3580 int movb;
3581 if (strcmp (name, "movb") == 0)
3582 movb = 8;
3583 else
3584 movb = 0;
3586 /* The existing operand extract code fell over if these additional modes
3587 were enabled in m68hc11-opc.c. So they are commented there and
3588 decoded here instead. */
3590 if (operands[1].mode & (M6812_OP_IDX | M6812_OP_IDX_1
3591 | M6812_OP_IDX_2 | M6812_OP_D_IDX | M6812_OP_D_IDX_2 | M6812_PRE_INC
3592 | M6812_PRE_DEC | M6812_POST_INC | M6812_POST_DEC ))
3594 /* first check if valid mode then start building it up */
3595 if (operands[0].mode & (M6811_OP_IMM8 | M6811_OP_IMM16
3596 | M6811_OP_IND16 | M6812_OP_IDX | M6812_OP_IDX_1
3597 | M6812_OP_IDX_2 | M6812_OP_D_IDX | M6812_OP_D_IDX_2))
3599 int opr16a;
3600 if (operands[1].mode & (M6811_OP_IND16))
3601 opr16a = 3;
3602 else
3603 opr16a = 0;
3605 f = m68hc11_new_insn (2);
3607 if (operands[0].mode & (M6811_OP_IMM8 | M6811_OP_IMM16))
3609 number_to_chars_bigendian (f, 0x1800 + movb + opr16a, 2);
3610 build_indexed_byte (&operands[1], operands[1].mode, 1);
3611 if (movb)
3612 fixup8 (&operands[0].exp, M6811_OP_IMM8,
3613 operands[0].mode);
3614 else
3615 fixup16 (&operands[0].exp, M6811_OP_IMM16,
3616 operands[0].mode);
3618 return;
3620 else if (operands[0].mode & M6811_OP_IND16)
3622 number_to_chars_bigendian (f, 0x1801 + movb + opr16a, 2);
3623 build_indexed_byte (&operands[1], operands[1].mode, 1);
3624 fixup16 (&operands[0].exp, M6811_OP_IND16, operands[0].mode);
3625 return;
3627 else
3629 number_to_chars_bigendian (f, 0x1802 + movb + opr16a, 2);
3630 build_indexed_byte (&operands[0], operands[0].mode, 1);
3631 build_indexed_byte (&operands[1], operands[1].mode, 1);
3632 return;
3636 else if (operands[1].mode & M6811_OP_IND16)
3638 /* First check if this is valid mode, then start building it up. */
3639 if (operands[0].mode & (M6811_OP_IMM8 | M6811_OP_IMM16
3640 | M6811_OP_IND16 | M6812_OP_IDX | M6812_OP_IDX_1
3641 | M6812_OP_IDX_2 | M6812_OP_D_IDX | M6812_OP_D_IDX_2))
3643 int opr16a;
3644 if (operands[1].mode & (M6811_OP_IND16))
3645 opr16a = 3;
3646 else
3647 opr16a = 0;
3649 f = m68hc11_new_insn (2);
3651 /* The first two cases here should actually be covered by the
3652 normal operand code. */
3653 if (operands[0].mode & (M6811_OP_IMM8 | M6811_OP_IMM16))
3655 number_to_chars_bigendian (f, 0x1800 + movb + opr16a, 2);
3656 if (movb)
3657 fixup8 (&operands[0].exp, M6811_OP_IMM8, operands[0].mode);
3658 else
3659 fixup16 (&operands[0].exp, M6811_OP_IMM16, operands[0].mode);
3661 fixup16 (&operands[0].exp, M6811_OP_IND16, operands[0].mode);
3662 return;
3664 else if (operands[0].mode & M6811_OP_IND16)
3666 number_to_chars_bigendian (f, 0x1801 + movb + opr16a, 2);
3667 build_indexed_byte (&operands[1], operands[1].mode, 1);
3668 fixup16 (&operands[0].exp, M6811_OP_IND16, operands[0].mode);
3669 return;
3671 else
3673 number_to_chars_bigendian (f, 0x1802 + movb + opr16a, 2);
3674 build_indexed_byte (&operands[0], operands[0].mode, 1);
3675 fixup16 (&operands[1].exp, M6811_OP_IND16, operands[1].mode);
3676 return;
3681 as_bad (_("Invalid operand for `%s'"), name);
3682 return;
3685 else
3687 as_bad (_("Invalid operand for `%s'"), name);
3688 return;
3692 /* Treat dbeq/ibeq/tbeq instructions in a special way. The branch is
3693 relative and must be in the range -256..255 (9-bits). */
3694 if ((opcode->format & M6812_XBCC_MARKER)
3695 && (opcode->format & M6811_OP_JUMP_REL))
3696 build_dbranch_insn (opcode, operands, nb_operands, branch_optimize);
3698 /* Relative jumps instructions are taken care of separately. We have to make
3699 sure that the relative branch is within the range -128..127. If it's out
3700 of range, the instructions are changed into absolute instructions.
3701 This is not supported for the brset and brclr instructions. */
3702 else if ((opcode->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
3703 && !(opcode->format & M6811_OP_BITMASK))
3704 build_jump_insn (opcode, operands, nb_operands, branch_optimize);
3705 else
3706 build_insn (opcode, operands, nb_operands);
3710 /* Pseudo op to control the ELF flags. */
3711 static void
3712 s_m68hc11_mode (int x ATTRIBUTE_UNUSED)
3714 char *name = input_line_pointer, ch;
3716 while (!is_end_of_line[(unsigned char) *input_line_pointer])
3717 input_line_pointer++;
3718 ch = *input_line_pointer;
3719 *input_line_pointer = '\0';
3721 if (strcmp (name, "mshort") == 0)
3723 elf_flags &= ~E_M68HC11_I32;
3725 else if (strcmp (name, "mlong") == 0)
3727 elf_flags |= E_M68HC11_I32;
3729 else if (strcmp (name, "mshort-double") == 0)
3731 elf_flags &= ~E_M68HC11_F64;
3733 else if (strcmp (name, "mlong-double") == 0)
3735 elf_flags |= E_M68HC11_F64;
3737 else
3739 as_warn (_("Invalid mode: %s\n"), name);
3741 *input_line_pointer = ch;
3742 demand_empty_rest_of_line ();
3745 /* Mark the symbols with STO_M68HC12_FAR to indicate the functions
3746 are using 'rtc' for returning. It is necessary to use 'call'
3747 to invoke them. This is also used by the debugger to correctly
3748 find the stack frame. */
3749 static void
3750 s_m68hc11_mark_symbol (int mark)
3752 char *name;
3753 int c;
3754 symbolS *symbolP;
3755 asymbol *bfdsym;
3756 elf_symbol_type *elfsym;
3760 c = get_symbol_name (&name);
3761 symbolP = symbol_find_or_make (name);
3762 (void) restore_line_pointer (c);
3764 SKIP_WHITESPACE ();
3766 bfdsym = symbol_get_bfdsym (symbolP);
3767 elfsym = elf_symbol_from (bfdsym);
3769 gas_assert (elfsym);
3771 /* Mark the symbol far (using rtc for function return). */
3772 elfsym->internal_elf_sym.st_other |= mark;
3774 if (c == ',')
3776 input_line_pointer ++;
3778 SKIP_WHITESPACE ();
3780 if (*input_line_pointer == '\n')
3781 c = '\n';
3784 while (c == ',');
3786 demand_empty_rest_of_line ();
3789 static void
3790 s_m68hc11_relax (int ignore ATTRIBUTE_UNUSED)
3792 expressionS ex;
3794 expression (&ex);
3796 if (ex.X_op != O_symbol || ex.X_add_number != 0)
3798 as_bad (_("bad .relax format"));
3799 ignore_rest_of_line ();
3800 return;
3803 fix_new_exp (frag_now, frag_now_fix (), 0, &ex, 1,
3804 BFD_RELOC_M68HC11_RL_GROUP);
3806 demand_empty_rest_of_line ();
3810 /* Relocation, relaxation and frag conversions. */
3812 /* PC-relative offsets are relative to the start of the
3813 next instruction. That is, the address of the offset, plus its
3814 size, since the offset is always the last part of the insn. */
3815 long
3816 md_pcrel_from (fixS *fixP)
3818 if (fixP->fx_r_type == BFD_RELOC_M68HC11_RL_JUMP)
3819 return 0;
3821 return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
3824 /* If while processing a fixup, a reloc really needs to be created
3825 then it is done here. */
3826 arelent *
3827 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
3829 arelent *reloc;
3831 reloc = XNEW (arelent);
3832 reloc->sym_ptr_ptr = XNEW (asymbol *);
3833 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
3834 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
3835 if (fixp->fx_r_type == 0)
3836 reloc->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_16);
3837 else
3838 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
3839 if (reloc->howto == (reloc_howto_type *) NULL)
3841 as_bad_where (fixp->fx_file, fixp->fx_line,
3842 _("Relocation %d is not supported by object file format."),
3843 (int) fixp->fx_r_type);
3844 return NULL;
3847 /* Since we use Rel instead of Rela, encode the vtable entry to be
3848 used in the relocation's section offset. */
3849 if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
3850 reloc->address = fixp->fx_offset;
3852 reloc->addend = 0;
3853 return reloc;
3856 /* We need a port-specific relaxation function to cope with sym2 - sym1
3857 relative expressions with both symbols in the same segment (but not
3858 necessarily in the same frag as this insn), for example:
3859 ldab sym2-(sym1-2),pc
3860 sym1:
3861 The offset can be 5, 9 or 16 bits long. */
3863 long
3864 m68hc11_relax_frag (segT seg ATTRIBUTE_UNUSED, fragS *fragP,
3865 long stretch ATTRIBUTE_UNUSED)
3867 long growth;
3868 offsetT aim = 0;
3869 symbolS *symbolP;
3870 const relax_typeS *this_type;
3871 const relax_typeS *start_type;
3872 relax_substateT next_state;
3873 relax_substateT this_state;
3874 const relax_typeS *table = TC_GENERIC_RELAX_TABLE;
3876 /* We only have to cope with frags as prepared by
3877 md_estimate_size_before_relax. The STATE_BITS16 case may get here
3878 because of the different reasons that it's not relaxable. */
3879 switch (fragP->fr_subtype)
3881 case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS16):
3882 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16):
3883 /* When we get to this state, the frag won't grow any more. */
3884 return 0;
3886 case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS5):
3887 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS5):
3888 case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS9):
3889 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9):
3890 if (fragP->fr_symbol == NULL
3891 || S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
3892 as_fatal (_("internal inconsistency problem in %s: fr_symbol %lx"),
3893 __func__, (long) fragP->fr_symbol);
3894 symbolP = fragP->fr_symbol;
3895 if (symbol_resolved_p (symbolP))
3896 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
3897 __func__);
3898 aim = S_GET_VALUE (symbolP);
3899 break;
3901 default:
3902 as_fatal (_("internal inconsistency problem in %s: fr_subtype %d"),
3903 __func__, fragP->fr_subtype);
3906 /* The rest is stolen from relax_frag. There's no obvious way to
3907 share the code, but fortunately no requirement to keep in sync as
3908 long as fragP->fr_symbol does not have its segment changed. */
3910 this_state = fragP->fr_subtype;
3911 start_type = this_type = table + this_state;
3913 if (aim < 0)
3915 /* Look backwards. */
3916 for (next_state = this_type->rlx_more; next_state;)
3917 if (aim >= this_type->rlx_backward)
3918 next_state = 0;
3919 else
3921 /* Grow to next state. */
3922 this_state = next_state;
3923 this_type = table + this_state;
3924 next_state = this_type->rlx_more;
3927 else
3929 /* Look forwards. */
3930 for (next_state = this_type->rlx_more; next_state;)
3931 if (aim <= this_type->rlx_forward)
3932 next_state = 0;
3933 else
3935 /* Grow to next state. */
3936 this_state = next_state;
3937 this_type = table + this_state;
3938 next_state = this_type->rlx_more;
3942 growth = this_type->rlx_length - start_type->rlx_length;
3943 if (growth != 0)
3944 fragP->fr_subtype = this_state;
3945 return growth;
3948 void
3949 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, asection *sec ATTRIBUTE_UNUSED,
3950 fragS *fragP)
3952 long value;
3953 long disp;
3954 char *buffer_address = fragP->fr_literal;
3956 /* Address in object code of the displacement. */
3957 int object_address = fragP->fr_fix + fragP->fr_address;
3959 buffer_address += fragP->fr_fix;
3961 /* The displacement of the address, from current location. */
3962 value = S_GET_VALUE (fragP->fr_symbol);
3963 disp = (value + fragP->fr_offset) - object_address;
3965 switch (fragP->fr_subtype)
3967 case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE):
3968 fragP->fr_opcode[1] = disp;
3969 break;
3971 case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD):
3972 /* This relax is only for bsr and bra. */
3973 gas_assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
3974 || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
3975 || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
3977 fragP->fr_opcode[0] = convert_branch (fragP->fr_opcode[0]);
3979 fix_new (fragP, fragP->fr_fix - 1, 2,
3980 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
3981 fragP->fr_fix += 1;
3982 break;
3984 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_BYTE):
3985 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_BYTE):
3986 fragP->fr_opcode[1] = disp;
3987 break;
3989 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_WORD):
3990 /* Invert branch. */
3991 fragP->fr_opcode[0] ^= 1;
3992 fragP->fr_opcode[1] = 3; /* Branch offset. */
3993 buffer_address[0] = M6811_JMP;
3994 fix_new (fragP, fragP->fr_fix + 1, 2,
3995 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
3996 fragP->fr_fix += 3;
3997 break;
3999 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_WORD):
4000 /* Translate branch into a long branch. */
4001 fragP->fr_opcode[1] = fragP->fr_opcode[0];
4002 fragP->fr_opcode[0] = M6811_OPCODE_PAGE2;
4004 fix_new (fragP, fragP->fr_fix, 2,
4005 fragP->fr_symbol, fragP->fr_offset, 1,
4006 BFD_RELOC_16_PCREL);
4007 fragP->fr_fix += 2;
4008 break;
4010 case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS5):
4011 if (fragP->fr_symbol != 0
4012 && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
4013 value = disp;
4014 /* fall through */
4016 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS5):
4017 fragP->fr_opcode[0] = fragP->fr_opcode[0] << 6;
4018 fragP->fr_opcode[0] |= value & 0x1f;
4019 break;
4021 case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS9):
4022 /* For a PC-relative offset, use the displacement with a -1 correction
4023 to take into account the additional byte of the insn. */
4024 if (fragP->fr_symbol != 0
4025 && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
4026 value = disp - 1;
4027 /* fall through */
4029 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9):
4030 fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3);
4031 fragP->fr_opcode[0] |= 0xE0;
4032 fragP->fr_opcode[0] |= (value >> 8) & 1;
4033 fragP->fr_opcode[1] = value;
4034 fragP->fr_fix += 1;
4035 break;
4037 case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS16):
4038 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16):
4039 fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3);
4040 fragP->fr_opcode[0] |= 0xe2;
4041 if ((fragP->fr_opcode[0] & 0x0ff) == 0x0fa
4042 && fragP->fr_symbol != 0
4043 && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
4045 fix_new (fragP, fragP->fr_fix, 2,
4046 fragP->fr_symbol, fragP->fr_offset,
4047 1, BFD_RELOC_16_PCREL);
4049 else
4051 fix_new (fragP, fragP->fr_fix, 2,
4052 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
4054 fragP->fr_fix += 2;
4055 break;
4057 case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_BYTE):
4058 if (disp < 0)
4059 fragP->fr_opcode[0] |= 0x10;
4061 fragP->fr_opcode[1] = disp & 0x0FF;
4062 break;
4064 case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_WORD):
4065 /* Invert branch. */
4066 fragP->fr_opcode[0] ^= 0x20;
4067 fragP->fr_opcode[1] = 3; /* Branch offset. */
4068 buffer_address[0] = M6812_JMP;
4069 fix_new (fragP, fragP->fr_fix + 1, 2,
4070 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
4071 fragP->fr_fix += 3;
4072 break;
4074 default:
4075 break;
4079 /* On an ELF system, we can't relax a weak symbol. The weak symbol
4080 can be overridden at final link time by a non weak symbol. We can
4081 relax externally visible symbol because there is no shared library
4082 and such symbol can't be overridden (unless they are weak). */
4083 static int
4084 relaxable_symbol (symbolS *symbol)
4086 return ! S_IS_WEAK (symbol);
4089 /* Force truly undefined symbols to their maximum size, and generally set up
4090 the frag list to be relaxed. */
4092 md_estimate_size_before_relax (fragS *fragP, asection *segment)
4094 if (RELAX_LENGTH (fragP->fr_subtype) == STATE_UNDF)
4096 if (S_GET_SEGMENT (fragP->fr_symbol) != segment
4097 || !relaxable_symbol (fragP->fr_symbol)
4098 || (segment != absolute_section
4099 && RELAX_STATE (fragP->fr_subtype) == STATE_INDEXED_OFFSET))
4101 /* Non-relaxable cases. */
4102 int old_fr_fix;
4103 char *buffer_address;
4105 old_fr_fix = fragP->fr_fix;
4106 buffer_address = fragP->fr_fix + fragP->fr_literal;
4108 switch (RELAX_STATE (fragP->fr_subtype))
4110 case STATE_PC_RELATIVE:
4112 /* This relax is only for bsr and bra. */
4113 gas_assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
4114 || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
4115 || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
4117 if (flag_fixed_branches)
4118 as_bad_where (fragP->fr_file, fragP->fr_line,
4119 _("bra or bsr with undefined symbol."));
4121 /* The symbol is undefined or in a separate section.
4122 Turn bra into a jmp and bsr into a jsr. The insn
4123 becomes 3 bytes long (instead of 2). A fixup is
4124 necessary for the unresolved symbol address. */
4125 fragP->fr_opcode[0] = convert_branch (fragP->fr_opcode[0]);
4127 fix_new (fragP, fragP->fr_fix - 1, 2, fragP->fr_symbol,
4128 fragP->fr_offset, 0, BFD_RELOC_16);
4129 fragP->fr_fix++;
4130 break;
4132 case STATE_CONDITIONAL_BRANCH:
4133 gas_assert (current_architecture & cpu6811);
4135 fragP->fr_opcode[0] ^= 1; /* Reverse sense of branch. */
4136 fragP->fr_opcode[1] = 3; /* Skip next jmp insn (3 bytes). */
4138 /* Don't use fr_opcode[2] because this may be
4139 in a different frag. */
4140 buffer_address[0] = M6811_JMP;
4142 fragP->fr_fix++;
4143 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
4144 fragP->fr_offset, 0, BFD_RELOC_16);
4145 fragP->fr_fix += 2;
4146 break;
4148 case STATE_INDEXED_OFFSET:
4149 gas_assert (current_architecture & cpu6812);
4151 if (fragP->fr_symbol
4152 && S_GET_SEGMENT (fragP->fr_symbol) == absolute_section)
4154 fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_OFFSET,
4155 STATE_BITS5);
4156 /* Return the size of the variable part of the frag. */
4157 return md_relax_table[fragP->fr_subtype].rlx_length;
4159 else
4161 /* Switch the indexed operation to 16-bit mode. */
4162 fragP->fr_opcode[0] = fragP->fr_opcode[0] << 3;
4163 fragP->fr_opcode[0] |= 0xe2;
4164 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
4165 fragP->fr_offset, 0, BFD_RELOC_16);
4166 fragP->fr_fix += 2;
4168 break;
4170 case STATE_INDEXED_PCREL:
4171 gas_assert (current_architecture & cpu6812);
4173 if (fragP->fr_symbol
4174 && S_GET_SEGMENT (fragP->fr_symbol) == absolute_section)
4176 fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_PCREL,
4177 STATE_BITS5);
4178 /* Return the size of the variable part of the frag. */
4179 return md_relax_table[fragP->fr_subtype].rlx_length;
4181 else
4183 fragP->fr_opcode[0] = fragP->fr_opcode[0] << 3;
4184 fragP->fr_opcode[0] |= 0xe2;
4185 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
4186 fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
4187 fragP->fr_fix += 2;
4189 break;
4191 case STATE_XBCC_BRANCH:
4192 gas_assert (current_architecture & cpu6812);
4194 fragP->fr_opcode[0] ^= 0x20; /* Reverse sense of branch. */
4195 fragP->fr_opcode[1] = 3; /* Skip next jmp insn (3 bytes). */
4197 /* Don't use fr_opcode[2] because this may be
4198 in a different frag. */
4199 buffer_address[0] = M6812_JMP;
4201 fragP->fr_fix++;
4202 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
4203 fragP->fr_offset, 0, BFD_RELOC_16);
4204 fragP->fr_fix += 2;
4205 break;
4207 case STATE_CONDITIONAL_BRANCH_6812:
4208 gas_assert (current_architecture & cpu6812);
4210 /* Translate into a lbcc branch. */
4211 fragP->fr_opcode[1] = fragP->fr_opcode[0];
4212 fragP->fr_opcode[0] = M6811_OPCODE_PAGE2;
4214 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
4215 fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
4216 fragP->fr_fix += 2;
4217 break;
4219 default:
4220 as_fatal (_("Subtype %d is not recognized."), fragP->fr_subtype);
4222 frag_wane (fragP);
4224 /* Return the growth in the fixed part of the frag. */
4225 return fragP->fr_fix - old_fr_fix;
4228 /* Relaxable cases. */
4229 switch (RELAX_STATE (fragP->fr_subtype))
4231 case STATE_PC_RELATIVE:
4232 /* This relax is only for bsr and bra. */
4233 gas_assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
4234 || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
4235 || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
4237 fragP->fr_subtype = ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE);
4238 break;
4240 case STATE_CONDITIONAL_BRANCH:
4241 gas_assert (current_architecture & cpu6811);
4243 fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH,
4244 STATE_BYTE);
4245 break;
4247 case STATE_INDEXED_OFFSET:
4248 gas_assert (current_architecture & cpu6812);
4250 fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_OFFSET,
4251 STATE_BITS5);
4252 break;
4254 case STATE_INDEXED_PCREL:
4255 gas_assert (current_architecture & cpu6812);
4257 fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_PCREL,
4258 STATE_BITS5);
4259 break;
4261 case STATE_XBCC_BRANCH:
4262 gas_assert (current_architecture & cpu6812);
4264 fragP->fr_subtype = ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_BYTE);
4265 break;
4267 case STATE_CONDITIONAL_BRANCH_6812:
4268 gas_assert (current_architecture & cpu6812);
4270 fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812,
4271 STATE_BYTE);
4272 break;
4276 if (fragP->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))
4277 as_fatal (_("Subtype %d is not recognized."), fragP->fr_subtype);
4279 /* Return the size of the variable part of the frag. */
4280 return md_relax_table[fragP->fr_subtype].rlx_length;
4283 /* See whether we need to force a relocation into the output file. */
4285 tc_m68hc11_force_relocation (fixS *fixP)
4287 if (fixP->fx_r_type == BFD_RELOC_M68HC11_RL_GROUP)
4288 return 1;
4290 return generic_force_reloc (fixP);
4293 /* Here we decide which fixups can be adjusted to make them relative
4294 to the beginning of the section instead of the symbol. Basically
4295 we need to make sure that the linker relaxation is done
4296 correctly, so in some cases we force the original symbol to be
4297 used. */
4299 tc_m68hc11_fix_adjustable (fixS *fixP)
4301 switch (fixP->fx_r_type)
4303 /* For the linker relaxation to work correctly, these relocs
4304 need to be on the symbol itself. */
4305 case BFD_RELOC_16:
4306 case BFD_RELOC_M68HC11_RL_JUMP:
4307 case BFD_RELOC_M68HC11_RL_GROUP:
4308 case BFD_RELOC_VTABLE_INHERIT:
4309 case BFD_RELOC_VTABLE_ENTRY:
4310 case BFD_RELOC_32:
4312 /* The memory bank addressing translation also needs the original
4313 symbol. */
4314 case BFD_RELOC_M68HC11_LO16:
4315 case BFD_RELOC_M68HC11_PAGE:
4316 case BFD_RELOC_M68HC11_24:
4317 return 0;
4319 default:
4320 return 1;
4324 void
4325 md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
4327 char *where;
4328 long value = * valP;
4330 if (fixP->fx_addsy == (symbolS *) NULL)
4331 fixP->fx_done = 1;
4333 /* We don't actually support subtracting a symbol. */
4334 if (fixP->fx_subsy != (symbolS *) NULL)
4335 as_bad_subtract (fixP);
4337 /* Patch the instruction with the resolved operand. Elf relocation
4338 info will also be generated to take care of linker/loader fixups.
4339 The 68HC11 addresses only 64Kb, we are only concerned by 8 and 16-bit
4340 relocs. BFD_RELOC_8 is basically used for .page0 access (the linker
4341 will warn for overflows). BFD_RELOC_8_PCREL should not be generated
4342 because it's either resolved or turned out into non-relative insns (see
4343 relax table, bcc, bra, bsr transformations)
4345 The BFD_RELOC_32 is necessary for the support of --gstabs. */
4346 where = fixP->fx_frag->fr_literal + fixP->fx_where;
4348 switch (fixP->fx_r_type)
4350 case BFD_RELOC_32:
4351 bfd_putb32 ((bfd_vma) value, (unsigned char *) where);
4352 break;
4354 case BFD_RELOC_24:
4355 case BFD_RELOC_M68HC11_24:
4356 bfd_putb16 ((bfd_vma) (value & 0x0ffff), (unsigned char *) where);
4357 ((bfd_byte*) where)[2] = ((value >> 16) & 0x0ff);
4358 break;
4360 case BFD_RELOC_16:
4361 case BFD_RELOC_16_PCREL:
4362 case BFD_RELOC_M68HC11_LO16:
4363 bfd_putb16 ((bfd_vma) value, (unsigned char *) where);
4364 if (value < -65537 || value > 65535)
4365 as_bad_where (fixP->fx_file, fixP->fx_line,
4366 _("Value out of 16-bit range."));
4367 break;
4369 case BFD_RELOC_M68HC11_HI8:
4370 /* Caution, %hi(<symbol>+%ld) will generate incorrect code if %lo
4371 causes a carry. */
4372 case BFD_RELOC_M68HC12_HI8XG:
4373 value = value >> 8;
4374 /* Fall through. */
4376 case BFD_RELOC_M68HC12_LO8XG:
4377 case BFD_RELOC_M68HC11_LO8:
4378 case BFD_RELOC_8:
4379 case BFD_RELOC_M68HC11_PAGE:
4380 ((bfd_byte *) where)[0] = (bfd_byte) value;
4381 break;
4383 case BFD_RELOC_8_PCREL:
4384 ((bfd_byte *) where)[0] = (bfd_byte) value;
4386 if (value < -128 || value > 127)
4387 as_bad_where (fixP->fx_file, fixP->fx_line,
4388 _("Value %ld too large for 8-bit PC-relative branch."),
4389 value);
4390 break;
4392 /* These next two are for XGATE. */
4393 case BFD_RELOC_M68HC12_9_PCREL:
4394 ((bfd_byte *) where)[0] |= (bfd_byte) ((value >>9) & 0x01);
4395 ((bfd_byte *) where)[1] = (bfd_byte) ((value>>1) & 0xff);
4396 if (value < -512 || value > 511)
4397 as_bad_where (fixP->fx_file, fixP->fx_line,
4398 _("Value %ld too large for 9-bit PC-relative branch."),
4399 value);
4400 break;
4402 case BFD_RELOC_M68HC12_10_PCREL:
4403 ((bfd_byte *) where)[0] |= (bfd_byte) ((value >>9) & 0x03);
4404 ((bfd_byte *) where)[1] = (bfd_byte) ((value>>1) & 0xff);
4405 if (value < -1024 || value > 1023)
4406 as_bad_where (fixP->fx_file, fixP->fx_line,
4407 _("Value %ld too large for 10-bit PC-relative branch."),
4408 value);
4410 break;
4412 case BFD_RELOC_M68HC11_3B:
4413 if (value <= 0 || value > 8)
4414 as_bad_where (fixP->fx_file, fixP->fx_line,
4415 _("Auto increment/decrement offset '%ld' is out of range."),
4416 value);
4417 if (where[0] & 0x8)
4418 value = 8 - value;
4419 else
4420 value--;
4422 where[0] = where[0] | (value & 0x07);
4423 break;
4425 case BFD_RELOC_M68HC12_5B:
4426 if (value < -16 || value > 15)
4427 as_bad_where (fixP->fx_file, fixP->fx_line,
4428 _("Offset out of 5-bit range for movw/movb insn: %ld"),
4429 value);
4430 if (value >= 0)
4431 where[0] |= value;
4432 else
4433 where[0] |= (0x10 | (16 + value));
4434 break;
4436 case BFD_RELOC_M68HC12_9B:
4437 if (value < -256 || value > 255)
4438 as_bad_where (fixP->fx_file, fixP->fx_line,
4439 _("Offset out of 9-bit range for movw/movb insn: %ld"),
4440 value);
4441 /* sign bit already in xb postbyte */
4442 if (value >= 0)
4443 where[1] = value;
4444 else
4445 where[1] = (256 + value);
4446 break;
4448 case BFD_RELOC_M68HC12_16B:
4449 if (value < -32768 || value > 32767)
4450 as_bad_where (fixP->fx_file, fixP->fx_line,
4451 _("Offset out of 16-bit range for movw/movb insn: %ld"),
4452 value);
4453 if (value < 0)
4454 value += 65536;
4456 where[0] = (value >> 8);
4457 where[1] = (value & 0xff);
4458 break;
4460 case BFD_RELOC_M68HC11_RL_JUMP:
4461 case BFD_RELOC_M68HC11_RL_GROUP:
4462 case BFD_RELOC_VTABLE_INHERIT:
4463 case BFD_RELOC_VTABLE_ENTRY:
4464 fixP->fx_done = 0;
4465 return;
4467 default:
4468 as_fatal (_("Line %d: unknown relocation type: 0x%x."),
4469 fixP->fx_line, fixP->fx_r_type);
4473 /* Set the ELF specific flags. */
4474 void
4475 m68hc11_elf_final_processing (void)
4477 if (current_architecture & cpu6812s)
4478 elf_flags |= EF_M68HCS12_MACH;
4479 elf_elfheader (stdoutput)->e_flags &= ~EF_M68HC11_ABI;
4480 elf_elfheader (stdoutput)->e_flags |= elf_flags;
4483 /* Process directives specified via pseudo ops */
4484 static void
4485 s_m68hc11_parse_pseudo_instruction (int pseudo_insn)
4487 switch (pseudo_insn)
4489 case E_M68HC11_NO_BANK_WARNING:
4490 elf_flags |= E_M68HC11_NO_BANK_WARNING;
4491 break;
4492 default:
4493 as_bad (_("Invalid directive"));