2002-10-02 Nathanael Nerode <neroden@gcc.gnu.org>
[binutils.git] / gas / config / tc-m68hc11.c
blob254bf1eac0f3811fd5e984547f75467cbdfb87c2
1 /* tc-m68hc11.c -- Assembler code for the Motorola 68HC11 & 68HC12.
2 Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
3 Written by Stephane Carrez (stcarrez@nerim.fr)
5 This file is part of GAS, the GNU Assembler.
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 #include <stdio.h>
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_XBCC_BRANCH (4)
41 #define STATE_CONDITIONAL_BRANCH_6812 (5)
43 #define STATE_BYTE (0)
44 #define STATE_BITS5 (0)
45 #define STATE_WORD (1)
46 #define STATE_BITS9 (1)
47 #define STATE_LONG (2)
48 #define STATE_BITS16 (2)
49 #define STATE_UNDF (3) /* Symbol undefined in pass1 */
51 /* This macro has no side-effects. */
52 #define ENCODE_RELAX(what,length) (((what) << 2) + (length))
53 #define RELAX_STATE(s) ((s) >> 2)
54 #define RELAX_LENGTH(s) ((s) & 3)
56 #define IS_OPCODE(C1,C2) (((C1) & 0x0FF) == ((C2) & 0x0FF))
58 /* This table describes how you change sizes for the various types of variable
59 size expressions. This version only supports two kinds. */
61 /* The fields are:
62 How far Forward this mode will reach.
63 How far Backward this mode will reach.
64 How many bytes this mode will add to the size of the frag.
65 Which mode to go to if the offset won't fit in this one. */
67 relax_typeS md_relax_table[] = {
68 {1, 1, 0, 0}, /* First entries aren't used. */
69 {1, 1, 0, 0}, /* For no good reason except. */
70 {1, 1, 0, 0}, /* that the VAX doesn't either. */
71 {1, 1, 0, 0},
73 /* Relax for bcc <L>.
74 These insns are translated into b!cc +3 jmp L. */
75 {(127), (-128), 0, ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_WORD)},
76 {0, 0, 3, 0},
77 {1, 1, 0, 0},
78 {1, 1, 0, 0},
80 /* Relax for bsr <L> and bra <L>.
81 These insns are translated into jsr and jmp. */
82 {(127), (-128), 0, ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD)},
83 {0, 0, 1, 0},
84 {1, 1, 0, 0},
85 {1, 1, 0, 0},
87 /* Relax for indexed offset: 5-bits, 9-bits, 16-bits. */
88 {(15), (-16), 0, ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9)},
89 {(255), (-256), 1, ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16)},
90 {0, 0, 2, 0},
91 {1, 1, 0, 0},
93 /* Relax for dbeq/ibeq/tbeq r,<L>:
94 These insns are translated into db!cc +3 jmp L. */
95 {(255), (-256), 0, ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_WORD)},
96 {0, 0, 3, 0},
97 {1, 1, 0, 0},
98 {1, 1, 0, 0},
100 /* Relax for bcc <L> on 68HC12.
101 These insns are translated into lbcc <L>. */
102 {(127), (-128), 0, ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_WORD)},
103 {0, 0, 2, 0},
104 {1, 1, 0, 0},
105 {1, 1, 0, 0},
109 /* 68HC11 and 68HC12 registers. They are numbered according to the 68HC12. */
110 typedef enum register_id {
111 REG_NONE = -1,
112 REG_A = 0,
113 REG_B = 1,
114 REG_CCR = 2,
115 REG_D = 4,
116 REG_X = 5,
117 REG_Y = 6,
118 REG_SP = 7,
119 REG_PC = 8
120 } register_id;
122 typedef struct operand {
123 expressionS exp;
124 register_id reg1;
125 register_id reg2;
126 int mode;
127 } operand;
129 struct m68hc11_opcode_def {
130 long format;
131 int min_operands;
132 int max_operands;
133 int nb_modes;
134 int used;
135 struct m68hc11_opcode *opcode;
138 static struct m68hc11_opcode_def *m68hc11_opcode_defs = 0;
139 static int m68hc11_nb_opcode_defs = 0;
141 typedef struct alias {
142 const char *name;
143 const char *alias;
144 } alias;
146 static alias alias_opcodes[] = {
147 {"cpd", "cmpd"},
148 {"cpx", "cmpx"},
149 {"cpy", "cmpy"},
150 {0, 0}
153 /* Local functions. */
154 static register_id reg_name_search PARAMS ((char *));
155 static register_id register_name PARAMS ((void));
156 static int cmp_opcode PARAMS ((struct m68hc11_opcode *,
157 struct m68hc11_opcode *));
158 static char *print_opcode_format PARAMS ((struct m68hc11_opcode *, int));
159 static char *skip_whites PARAMS ((char *));
160 static int check_range PARAMS ((long, int));
161 static void print_opcode_list PARAMS ((void));
162 static void get_default_target PARAMS ((void));
163 static void print_insn_format PARAMS ((char *));
164 static int get_operand PARAMS ((operand *, int, long));
165 static void fixup8 PARAMS ((expressionS *, int, int));
166 static void fixup16 PARAMS ((expressionS *, int, int));
167 static void fixup24 PARAMS ((expressionS *, int, int));
168 static unsigned char convert_branch PARAMS ((unsigned char));
169 static char *m68hc11_new_insn PARAMS ((int));
170 static void build_dbranch_insn PARAMS ((struct m68hc11_opcode *,
171 operand *, int, int));
172 static int build_indexed_byte PARAMS ((operand *, int, int));
173 static int build_reg_mode PARAMS ((operand *, int));
175 static struct m68hc11_opcode *find
176 PARAMS ((struct m68hc11_opcode_def *, operand *, int));
177 static struct m68hc11_opcode *find_opcode
178 PARAMS ((struct m68hc11_opcode_def *, operand *, int *));
179 static void build_jump_insn
180 PARAMS ((struct m68hc11_opcode *, operand *, int, int));
181 static void build_insn
182 PARAMS ((struct m68hc11_opcode *, operand *, int));
183 static int relaxable_symbol PARAMS ((symbolS *));
185 /* Pseudo op to indicate a relax group. */
186 static void s_m68hc11_relax PARAMS((int));
188 /* Pseudo op to control the ELF flags. */
189 static void s_m68hc11_mode PARAMS ((int));
191 /* Mark the symbols with STO_M68HC12_FAR to indicate the functions
192 are using 'rtc' for returning. It is necessary to use 'call'
193 to invoke them. This is also used by the debugger to correctly
194 find the stack frame. */
195 static void s_m68hc11_mark_symbol PARAMS ((int));
197 /* Controls whether relative branches can be turned into long branches.
198 When the relative offset is too large, the insn are changed:
199 bra -> jmp
200 bsr -> jsr
201 bcc -> b!cc +3
202 jmp L
203 dbcc -> db!cc +3
204 jmp L
206 Setting the flag forbidds this. */
207 static short flag_fixed_branchs = 0;
209 /* Force to use long jumps (absolute) instead of relative branches. */
210 static short flag_force_long_jumps = 0;
212 /* Change the direct addressing mode into an absolute addressing mode
213 when the insn does not support direct addressing.
214 For example, "clr *ZD0" is normally not possible and is changed
215 into "clr ZDO". */
216 static short flag_strict_direct_addressing = 1;
218 /* When an opcode has invalid operand, print out the syntax of the opcode
219 to stderr. */
220 static short flag_print_insn_syntax = 0;
222 /* Dumps the list of instructions with syntax and then exit:
223 1 -> Only dumps the list (sorted by name)
224 2 -> Generate an example (or test) that can be compiled. */
225 static short flag_print_opcodes = 0;
227 /* Opcode hash table. */
228 static struct hash_control *m68hc11_hash;
230 /* Current cpu (either cpu6811 or cpu6812). This is determined automagically
231 by 'get_default_target' by looking at default BFD vector. This is overriden
232 with the -m<cpu> option. */
233 static int current_architecture = 0;
235 /* Default cpu determined by 'get_default_target'. */
236 static const char *default_cpu;
238 /* Number of opcodes in the sorted table (filtered by current cpu). */
239 static int num_opcodes;
241 /* The opcodes sorted by name and filtered by current cpu. */
242 static struct m68hc11_opcode *m68hc11_sorted_opcodes;
244 /* ELF flags to set in the output file header. */
245 static int elf_flags = 0;
247 /* These are the machine dependent pseudo-ops. These are included so
248 the assembler can work on the output from the SUN C compiler, which
249 generates these. */
251 /* This table describes all the machine specific pseudo-ops the assembler
252 has to support. The fields are:
253 pseudo-op name without dot
254 function to call to execute this pseudo-op
255 Integer arg to pass to the function. */
256 const pseudo_typeS md_pseudo_table[] = {
257 /* The following pseudo-ops are supported for MRI compatibility. */
258 {"fcb", cons, 1},
259 {"fdb", cons, 2},
260 {"fcc", stringer, 1},
261 {"rmb", s_space, 0},
263 /* Dwarf2 support for Gcc. */
264 {"file", (void (*) PARAMS ((int))) dwarf2_directive_file, 0},
265 {"loc", dwarf2_directive_loc, 0},
267 /* Motorola ALIS. */
268 {"xrefb", s_ignore, 0}, /* Same as xref */
270 /* Gcc driven relaxation. */
271 {"relax", s_m68hc11_relax, 0},
273 /* .mode instruction (ala SH). */
274 {"mode", s_m68hc11_mode, 0},
276 /* .far instruction. */
277 {"far", s_m68hc11_mark_symbol, STO_M68HC12_FAR},
279 /* .interrupt instruction. */
280 {"interrupt", s_m68hc11_mark_symbol, STO_M68HC12_INTERRUPT},
282 {0, 0, 0}
285 /* Options and initialization. */
287 const char *md_shortopts = "Sm:";
289 struct option md_longopts[] = {
290 #define OPTION_FORCE_LONG_BRANCH (OPTION_MD_BASE)
291 {"force-long-branchs", no_argument, NULL, OPTION_FORCE_LONG_BRANCH},
293 #define OPTION_SHORT_BRANCHS (OPTION_MD_BASE + 1)
294 {"short-branchs", no_argument, NULL, OPTION_SHORT_BRANCHS},
296 #define OPTION_STRICT_DIRECT_MODE (OPTION_MD_BASE + 2)
297 {"strict-direct-mode", no_argument, NULL, OPTION_STRICT_DIRECT_MODE},
299 #define OPTION_PRINT_INSN_SYNTAX (OPTION_MD_BASE + 3)
300 {"print-insn-syntax", no_argument, NULL, OPTION_PRINT_INSN_SYNTAX},
302 #define OPTION_PRINT_OPCODES (OPTION_MD_BASE + 4)
303 {"print-opcodes", no_argument, NULL, OPTION_PRINT_OPCODES},
305 #define OPTION_GENERATE_EXAMPLE (OPTION_MD_BASE + 5)
306 {"generate-example", no_argument, NULL, OPTION_GENERATE_EXAMPLE},
308 {NULL, no_argument, NULL, 0}
310 size_t md_longopts_size = sizeof (md_longopts);
312 /* Get the target cpu for the assembler. This is based on the configure
313 options and on the -m68hc11/-m68hc12 option. If no option is specified,
314 we must get the default. */
315 const char *
316 m68hc11_arch_format ()
318 get_default_target ();
319 if (current_architecture & cpu6811)
320 return "elf32-m68hc11";
321 else
322 return "elf32-m68hc12";
325 enum bfd_architecture
326 m68hc11_arch ()
328 get_default_target ();
329 if (current_architecture & cpu6811)
330 return bfd_arch_m68hc11;
331 else
332 return bfd_arch_m68hc12;
336 m68hc11_mach ()
338 return 0;
341 /* Listing header selected according to cpu. */
342 const char *
343 m68hc11_listing_header ()
345 if (current_architecture & cpu6811)
346 return "M68HC11 GAS ";
347 else
348 return "M68HC12 GAS ";
351 void
352 md_show_usage (stream)
353 FILE *stream;
355 get_default_target ();
356 fprintf (stream, _("\
357 Motorola 68HC11/68HC12 options:\n\
358 -m68hc11 | -m68hc12 specify the processor [default %s]\n\
359 --force-long-branchs always turn relative branchs into absolute ones\n\
360 -S,--short-branchs do not turn relative branchs into absolute ones\n\
361 when the offset is out of range\n\
362 --strict-direct-mode do not turn the direct mode into extended mode\n\
363 when the instruction does not support direct mode\n\
364 --print-insn-syntax print the syntax of instruction in case of error\n\
365 --print-opcodes print the list of instructions with syntax\n\
366 --generate-example generate an example of each instruction\n\
367 (used for testing)\n"), default_cpu);
371 /* Try to identify the default target based on the BFD library. */
372 static void
373 get_default_target ()
375 const bfd_target *target;
376 bfd abfd;
378 if (current_architecture != 0)
379 return;
381 default_cpu = "unknown";
382 target = bfd_find_target (0, &abfd);
383 if (target && target->name)
385 if (strcmp (target->name, "elf32-m68hc12") == 0)
387 current_architecture = cpu6812;
388 default_cpu = "m68hc12";
390 else if (strcmp (target->name, "elf32-m68hc11") == 0)
392 current_architecture = cpu6811;
393 default_cpu = "m68hc11";
395 else
397 as_bad (_("Default target `%s' is not supported."), target->name);
402 void
403 m68hc11_print_statistics (file)
404 FILE *file;
406 int i;
407 struct m68hc11_opcode_def *opc;
409 hash_print_statistics (file, "opcode table", m68hc11_hash);
411 opc = m68hc11_opcode_defs;
412 if (opc == 0 || m68hc11_nb_opcode_defs == 0)
413 return;
415 /* Dump the opcode statistics table. */
416 fprintf (file, _("Name # Modes Min ops Max ops Modes mask # Used\n"));
417 for (i = 0; i < m68hc11_nb_opcode_defs; i++, opc++)
419 fprintf (file, "%-7.7s %5d %7d %7d 0x%08lx %7d\n",
420 opc->opcode->name,
421 opc->nb_modes,
422 opc->min_operands, opc->max_operands, opc->format, opc->used);
427 md_parse_option (c, arg)
428 int c;
429 char *arg;
431 get_default_target ();
432 switch (c)
434 /* -S means keep external to 2 bit offset rather than 16 bit one. */
435 case OPTION_SHORT_BRANCHS:
436 case 'S':
437 flag_fixed_branchs = 1;
438 break;
440 case OPTION_FORCE_LONG_BRANCH:
441 flag_force_long_jumps = 1;
442 break;
444 case OPTION_PRINT_INSN_SYNTAX:
445 flag_print_insn_syntax = 1;
446 break;
448 case OPTION_PRINT_OPCODES:
449 flag_print_opcodes = 1;
450 break;
452 case OPTION_STRICT_DIRECT_MODE:
453 flag_strict_direct_addressing = 0;
454 break;
456 case OPTION_GENERATE_EXAMPLE:
457 flag_print_opcodes = 2;
458 break;
460 case 'm':
461 if (strcasecmp (arg, "68hc11") == 0)
462 current_architecture = cpu6811;
463 else if (strcasecmp (arg, "68hc12") == 0)
464 current_architecture = cpu6812;
465 else
466 as_bad (_("Option `%s' is not recognized."), arg);
467 break;
469 default:
470 return 0;
473 return 1;
476 symbolS *
477 md_undefined_symbol (name)
478 char *name ATTRIBUTE_UNUSED;
480 return 0;
483 /* Equal to MAX_PRECISION in atof-ieee.c. */
484 #define MAX_LITTLENUMS 6
486 /* Turn a string in input_line_pointer into a floating point constant
487 of type TYPE, and store the appropriate bytes in *LITP. The number
488 of LITTLENUMS emitted is stored in *SIZEP. An error message is
489 returned, or NULL on OK. */
490 char *
491 md_atof (type, litP, sizeP)
492 char type;
493 char *litP;
494 int *sizeP;
496 int prec;
497 LITTLENUM_TYPE words[MAX_LITTLENUMS];
498 LITTLENUM_TYPE *wordP;
499 char *t;
501 switch (type)
503 case 'f':
504 case 'F':
505 case 's':
506 case 'S':
507 prec = 2;
508 break;
510 case 'd':
511 case 'D':
512 case 'r':
513 case 'R':
514 prec = 4;
515 break;
517 case 'x':
518 case 'X':
519 prec = 6;
520 break;
522 case 'p':
523 case 'P':
524 prec = 6;
525 break;
527 default:
528 *sizeP = 0;
529 return _("Bad call to MD_ATOF()");
531 t = atof_ieee (input_line_pointer, type, words);
532 if (t)
533 input_line_pointer = t;
535 *sizeP = prec * sizeof (LITTLENUM_TYPE);
536 for (wordP = words; prec--;)
538 md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE));
539 litP += sizeof (LITTLENUM_TYPE);
541 return 0;
544 valueT
545 md_section_align (seg, addr)
546 asection *seg;
547 valueT addr;
549 int align = bfd_get_section_alignment (stdoutput, seg);
550 return ((addr + (1 << align) - 1) & (-1 << align));
553 static int
554 cmp_opcode (op1, op2)
555 struct m68hc11_opcode *op1;
556 struct m68hc11_opcode *op2;
558 return strcmp (op1->name, op2->name);
561 #define IS_CALL_SYMBOL(MODE) \
562 (((MODE) & (M6812_OP_PAGE|M6811_OP_IND16)) \
563 == ((M6812_OP_PAGE|M6811_OP_IND16)))
565 /* Initialize the assembler. Create the opcode hash table
566 (sorted on the names) with the M6811 opcode table
567 (from opcode library). */
568 void
569 md_begin ()
571 char *prev_name = "";
572 struct m68hc11_opcode *opcodes;
573 struct m68hc11_opcode_def *opc = 0;
574 int i, j;
576 get_default_target ();
578 m68hc11_hash = hash_new ();
580 /* Get a writable copy of the opcode table and sort it on the names. */
581 opcodes = (struct m68hc11_opcode *) xmalloc (m68hc11_num_opcodes *
582 sizeof (struct
583 m68hc11_opcode));
584 m68hc11_sorted_opcodes = opcodes;
585 num_opcodes = 0;
586 for (i = 0; i < m68hc11_num_opcodes; i++)
588 if (m68hc11_opcodes[i].arch & current_architecture)
590 opcodes[num_opcodes] = m68hc11_opcodes[i];
591 if (opcodes[num_opcodes].name[0] == 'b'
592 && opcodes[num_opcodes].format & M6811_OP_JUMP_REL
593 && !(opcodes[num_opcodes].format & M6811_OP_BITMASK))
595 num_opcodes++;
596 opcodes[num_opcodes] = m68hc11_opcodes[i];
598 num_opcodes++;
599 for (j = 0; alias_opcodes[j].name != 0; j++)
600 if (strcmp (m68hc11_opcodes[i].name, alias_opcodes[j].name) == 0)
602 opcodes[num_opcodes] = m68hc11_opcodes[i];
603 opcodes[num_opcodes].name = alias_opcodes[j].alias;
604 num_opcodes++;
605 break;
609 qsort (opcodes, num_opcodes, sizeof (struct m68hc11_opcode), cmp_opcode);
611 opc = (struct m68hc11_opcode_def *)
612 xmalloc (num_opcodes * sizeof (struct m68hc11_opcode_def));
613 m68hc11_opcode_defs = opc--;
615 /* Insert unique names into hash table. The M6811 instruction set
616 has several identical opcode names that have different opcodes based
617 on the operands. This hash table then provides a quick index to
618 the first opcode with a particular name in the opcode table. */
619 for (i = 0; i < num_opcodes; i++, opcodes++)
621 int expect;
623 if (strcmp (prev_name, opcodes->name))
625 prev_name = (char *) opcodes->name;
627 opc++;
628 opc->format = 0;
629 opc->min_operands = 100;
630 opc->max_operands = 0;
631 opc->nb_modes = 0;
632 opc->opcode = opcodes;
633 opc->used = 0;
634 hash_insert (m68hc11_hash, opcodes->name, (char *) opc);
636 opc->nb_modes++;
637 opc->format |= opcodes->format;
639 /* See how many operands this opcode needs. */
640 expect = 0;
641 if (opcodes->format & M6811_OP_MASK)
642 expect++;
643 if (opcodes->format & M6811_OP_BITMASK)
644 expect++;
645 if (opcodes->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
646 expect++;
647 if (opcodes->format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2))
648 expect++;
649 /* Special case for call instruction. */
650 if ((opcodes->format & M6812_OP_PAGE)
651 && !(opcodes->format & M6811_OP_IND16))
652 expect++;
654 if (expect < opc->min_operands)
655 opc->min_operands = expect;
656 if (IS_CALL_SYMBOL (opcodes->format))
657 expect++;
658 if (expect > opc->max_operands)
659 opc->max_operands = expect;
661 opc++;
662 m68hc11_nb_opcode_defs = opc - m68hc11_opcode_defs;
664 if (flag_print_opcodes)
666 print_opcode_list ();
667 exit (EXIT_SUCCESS);
671 void
672 m68hc11_init_after_args ()
676 /* Builtin help. */
678 /* Return a string that represents the operand format for the instruction.
679 When example is true, this generates an example of operand. This is used
680 to give an example and also to generate a test. */
681 static char *
682 print_opcode_format (opcode, example)
683 struct m68hc11_opcode *opcode;
684 int example;
686 static char buf[128];
687 int format = opcode->format;
688 char *p;
690 p = buf;
691 buf[0] = 0;
692 if (format & M6811_OP_IMM8)
694 if (example)
695 sprintf (p, "#%d", rand () & 0x0FF);
696 else
697 strcpy (p, _("#<imm8>"));
698 p = &p[strlen (p)];
701 if (format & M6811_OP_IMM16)
703 if (example)
704 sprintf (p, "#%d", rand () & 0x0FFFF);
705 else
706 strcpy (p, _("#<imm16>"));
707 p = &p[strlen (p)];
710 if (format & M6811_OP_IX)
712 if (example)
713 sprintf (p, "%d,X", rand () & 0x0FF);
714 else
715 strcpy (p, _("<imm8>,X"));
716 p = &p[strlen (p)];
719 if (format & M6811_OP_IY)
721 if (example)
722 sprintf (p, "%d,X", rand () & 0x0FF);
723 else
724 strcpy (p, _("<imm8>,X"));
725 p = &p[strlen (p)];
728 if (format & M6812_OP_IDX)
730 if (example)
731 sprintf (p, "%d,X", rand () & 0x0FF);
732 else
733 strcpy (p, "n,r");
734 p = &p[strlen (p)];
737 if (format & M6812_OP_PAGE)
739 if (example)
740 sprintf (p, ", %d", rand () & 0x0FF);
741 else
742 strcpy (p, ", <page>");
743 p = &p[strlen (p)];
746 if (format & M6811_OP_DIRECT)
748 if (example)
749 sprintf (p, "*Z%d", rand () & 0x0FF);
750 else
751 strcpy (p, _("*<abs8>"));
752 p = &p[strlen (p)];
755 if (format & M6811_OP_BITMASK)
757 if (buf[0])
758 *p++ = ' ';
760 if (example)
761 sprintf (p, "#$%02x", rand () & 0x0FF);
762 else
763 strcpy (p, _("#<mask>"));
765 p = &p[strlen (p)];
766 if (format & M6811_OP_JUMP_REL)
767 *p++ = ' ';
770 if (format & M6811_OP_IND16)
772 if (example)
773 sprintf (p, _("symbol%d"), rand () & 0x0FF);
774 else
775 strcpy (p, _("<abs>"));
777 p = &p[strlen (p)];
780 if (format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
782 if (example)
784 if (format & M6811_OP_BITMASK)
786 sprintf (p, ".+%d", rand () & 0x7F);
788 else
790 sprintf (p, "L%d", rand () & 0x0FF);
793 else
794 strcpy (p, _("<label>"));
797 return buf;
800 /* Prints the list of instructions with the possible operands. */
801 static void
802 print_opcode_list ()
804 int i;
805 char *prev_name = "";
806 struct m68hc11_opcode *opcodes;
807 int example = flag_print_opcodes == 2;
809 if (example)
810 printf (_("# Example of `%s' instructions\n\t.sect .text\n_start:\n"),
811 default_cpu);
813 opcodes = m68hc11_sorted_opcodes;
815 /* Walk the list sorted on names (by md_begin). We only report
816 one instruction per line, and we collect the different operand
817 formats. */
818 for (i = 0; i < num_opcodes; i++, opcodes++)
820 char *fmt = print_opcode_format (opcodes, example);
822 if (example)
824 printf ("L%d:\t", i);
825 printf ("%s %s\n", opcodes->name, fmt);
827 else
829 if (strcmp (prev_name, opcodes->name))
831 if (i > 0)
832 printf ("\n");
834 printf ("%-5.5s ", opcodes->name);
835 prev_name = (char *) opcodes->name;
837 if (fmt[0])
838 printf (" [%s]", fmt);
841 printf ("\n");
844 /* Print the instruction format. This operation is called when some
845 instruction is not correct. Instruction format is printed as an
846 error message. */
847 static void
848 print_insn_format (name)
849 char *name;
851 struct m68hc11_opcode_def *opc;
852 struct m68hc11_opcode *opcode;
853 char buf[128];
855 opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash, name);
856 if (opc == NULL)
858 as_bad (_("Instruction `%s' is not recognized."), name);
859 return;
861 opcode = opc->opcode;
863 as_bad (_("Instruction formats for `%s':"), name);
866 char *fmt;
868 fmt = print_opcode_format (opcode, 0);
869 sprintf (buf, "\t%-5.5s %s", opcode->name, fmt);
871 as_bad ("%s", buf);
872 opcode++;
874 while (strcmp (opcode->name, name) == 0);
877 /* Analysis of 68HC11 and 68HC12 operands. */
879 /* reg_name_search() finds the register number given its name.
880 Returns the register number or REG_NONE on failure. */
881 static register_id
882 reg_name_search (name)
883 char *name;
885 if (strcasecmp (name, "x") == 0 || strcasecmp (name, "ix") == 0)
886 return REG_X;
887 if (strcasecmp (name, "y") == 0 || strcasecmp (name, "iy") == 0)
888 return REG_Y;
889 if (strcasecmp (name, "a") == 0)
890 return REG_A;
891 if (strcasecmp (name, "b") == 0)
892 return REG_B;
893 if (strcasecmp (name, "d") == 0)
894 return REG_D;
895 if (strcasecmp (name, "sp") == 0)
896 return REG_SP;
897 if (strcasecmp (name, "pc") == 0)
898 return REG_PC;
899 if (strcasecmp (name, "ccr") == 0)
900 return REG_CCR;
902 return REG_NONE;
905 static char *
906 skip_whites (p)
907 char *p;
909 while (*p == ' ' || *p == '\t')
910 p++;
912 return p;
915 /* Check the string at input_line_pointer
916 to see if it is a valid register name. */
917 static register_id
918 register_name ()
920 register_id reg_number;
921 char c, *p = input_line_pointer;
923 if (!is_name_beginner (*p++))
924 return REG_NONE;
926 while (is_part_of_name (*p++))
927 continue;
929 c = *--p;
930 if (c)
931 *p++ = 0;
933 /* Look to see if it's in the register table. */
934 reg_number = reg_name_search (input_line_pointer);
935 if (reg_number != REG_NONE)
937 if (c)
938 *--p = c;
940 input_line_pointer = p;
941 return reg_number;
943 if (c)
944 *--p = c;
946 return reg_number;
949 /* Parse a string of operands and return an array of expressions.
951 Operand mode[0] mode[1] exp[0] exp[1]
952 #n M6811_OP_IMM16 - O_*
953 *<exp> M6811_OP_DIRECT - O_*
954 .{+-}<exp> M6811_OP_JUMP_REL - O_*
955 <exp> M6811_OP_IND16 - O_*
956 ,r N,r M6812_OP_IDX M6812_OP_REG O_constant O_register
957 n,-r M6812_PRE_DEC M6812_OP_REG O_constant O_register
958 n,+r M6812_PRE_INC " "
959 n,r- M6812_POST_DEC " "
960 n,r+ M6812_POST_INC " "
961 A,r B,r D,r M6811_OP_REG M6812_OP_REG O_register O_register
962 [D,r] M6811_OP_D_IDX M6812_OP_REG O_register O_register
963 [n,r] M6811_OP_D_IDX_2 M6812_OP_REG O_constant O_register */
964 static int
965 get_operand (oper, which, opmode)
966 operand *oper;
967 int which;
968 long opmode;
970 char *p = input_line_pointer;
971 int mode;
972 register_id reg;
974 oper->exp.X_op = O_absent;
975 oper->reg1 = REG_NONE;
976 oper->reg2 = REG_NONE;
977 mode = M6811_OP_NONE;
979 p = skip_whites (p);
981 if (*p == 0 || *p == '\n' || *p == '\r')
983 input_line_pointer = p;
984 return 0;
987 if (*p == '*' && (opmode & (M6811_OP_DIRECT | M6811_OP_IND16)))
989 mode = M6811_OP_DIRECT;
990 p++;
992 else if (*p == '#')
994 if (!(opmode & (M6811_OP_IMM8 | M6811_OP_IMM16 | M6811_OP_BITMASK)))
996 as_bad (_("Immediate operand is not allowed for operand %d."),
997 which);
998 return -1;
1001 mode = M6811_OP_IMM16;
1002 p++;
1003 if (strncmp (p, "%hi", 3) == 0)
1005 p += 3;
1006 mode |= M6811_OP_HIGH_ADDR;
1008 else if (strncmp (p, "%lo", 3) == 0)
1010 p += 3;
1011 mode |= M6811_OP_LOW_ADDR;
1014 else if (*p == '.' && (p[1] == '+' || p[1] == '-'))
1016 p++;
1017 mode = M6811_OP_JUMP_REL;
1019 else if (*p == '[')
1021 if (current_architecture & cpu6811)
1022 as_bad (_("Indirect indexed addressing is not valid for 68HC11."));
1024 p++;
1025 mode = M6812_OP_D_IDX;
1026 p = skip_whites (p);
1028 else if (*p == ',') /* Special handling of ,x and ,y. */
1030 p++;
1031 input_line_pointer = p;
1033 reg = register_name ();
1034 if (reg != REG_NONE)
1036 oper->reg1 = reg;
1037 oper->exp.X_op = O_constant;
1038 oper->exp.X_add_number = 0;
1039 oper->mode = M6812_OP_IDX;
1040 return 1;
1042 as_bad (_("Spurious `,' or bad indirect register addressing mode."));
1043 return -1;
1045 input_line_pointer = p;
1047 if (mode == M6811_OP_NONE || mode == M6812_OP_D_IDX)
1048 reg = register_name ();
1049 else
1050 reg = REG_NONE;
1052 if (reg != REG_NONE)
1054 p = skip_whites (input_line_pointer);
1055 if (*p == ']' && mode == M6812_OP_D_IDX)
1057 as_bad
1058 (_("Missing second register or offset for indexed-indirect mode."));
1059 return -1;
1062 oper->reg1 = reg;
1063 oper->mode = mode | M6812_OP_REG;
1064 if (*p != ',')
1066 if (mode == M6812_OP_D_IDX)
1068 as_bad (_("Missing second register for indexed-indirect mode."));
1069 return -1;
1071 return 1;
1074 p++;
1075 input_line_pointer = p;
1076 reg = register_name ();
1077 if (reg != REG_NONE)
1079 p = skip_whites (input_line_pointer);
1080 if (mode == M6812_OP_D_IDX)
1082 if (*p != ']')
1084 as_bad (_("Missing `]' to close indexed-indirect mode."));
1085 return -1;
1087 p++;
1088 oper->mode = M6812_OP_D_IDX;
1090 input_line_pointer = p;
1092 oper->reg2 = reg;
1093 return 1;
1095 return 1;
1098 /* In MRI mode, isolate the operand because we can't distinguish
1099 operands from comments. */
1100 if (flag_mri)
1102 char c = 0;
1104 p = skip_whites (p);
1105 while (*p && *p != ' ' && *p != '\t')
1106 p++;
1108 if (*p)
1110 c = *p;
1111 *p = 0;
1114 /* Parse as an expression. */
1115 expression (&oper->exp);
1117 if (c)
1119 *p = c;
1122 else
1124 expression (&oper->exp);
1127 if (oper->exp.X_op == O_illegal)
1129 as_bad (_("Illegal operand."));
1130 return -1;
1132 else if (oper->exp.X_op == O_absent)
1134 as_bad (_("Missing operand."));
1135 return -1;
1138 p = input_line_pointer;
1140 if (mode == M6811_OP_NONE || mode == M6811_OP_DIRECT
1141 || mode == M6812_OP_D_IDX)
1143 p = skip_whites (input_line_pointer);
1145 if (*p == ',')
1147 int possible_mode = M6811_OP_NONE;
1148 char *old_input_line;
1150 old_input_line = p;
1151 p++;
1153 /* 68HC12 pre increment or decrement. */
1154 if (mode == M6811_OP_NONE)
1156 if (*p == '-')
1158 possible_mode = M6812_PRE_DEC;
1159 p++;
1161 else if (*p == '+')
1163 possible_mode = M6812_PRE_INC;
1164 p++;
1166 p = skip_whites (p);
1168 input_line_pointer = p;
1169 reg = register_name ();
1171 /* Backtrack if we have a valid constant expression and
1172 it does not correspond to the offset of the 68HC12 indexed
1173 addressing mode (as in N,x). */
1174 if (reg == REG_NONE && mode == M6811_OP_NONE
1175 && possible_mode != M6811_OP_NONE)
1177 oper->mode = M6811_OP_IND16 | M6811_OP_JUMP_REL;
1178 input_line_pointer = skip_whites (old_input_line);
1179 return 1;
1182 if (possible_mode != M6811_OP_NONE)
1183 mode = possible_mode;
1185 if ((current_architecture & cpu6811)
1186 && possible_mode != M6811_OP_NONE)
1187 as_bad (_("Pre-increment mode is not valid for 68HC11"));
1188 /* Backtrack. */
1189 if (which == 0 && opmode & M6812_OP_IDX_P2
1190 && reg != REG_X && reg != REG_Y
1191 && reg != REG_PC && reg != REG_SP)
1193 reg = REG_NONE;
1194 input_line_pointer = p;
1197 if (reg == REG_NONE && mode != M6811_OP_DIRECT
1198 && !(mode == M6811_OP_NONE && opmode & M6811_OP_IND16))
1200 as_bad (_("Wrong register in register indirect mode."));
1201 return -1;
1203 if (mode == M6812_OP_D_IDX)
1205 p = skip_whites (input_line_pointer);
1206 if (*p++ != ']')
1208 as_bad (_("Missing `]' to close register indirect operand."));
1209 return -1;
1211 input_line_pointer = p;
1212 oper->reg1 = reg;
1213 oper->mode = M6812_OP_D_IDX_2;
1214 return 1;
1216 if (reg != REG_NONE)
1218 oper->reg1 = reg;
1219 if (mode == M6811_OP_NONE)
1221 p = input_line_pointer;
1222 if (*p == '-')
1224 mode = M6812_POST_DEC;
1225 p++;
1226 if (current_architecture & cpu6811)
1227 as_bad
1228 (_("Post-decrement mode is not valid for 68HC11."));
1230 else if (*p == '+')
1232 mode = M6812_POST_INC;
1233 p++;
1234 if (current_architecture & cpu6811)
1235 as_bad
1236 (_("Post-increment mode is not valid for 68HC11."));
1238 else
1239 mode = M6812_OP_IDX;
1241 input_line_pointer = p;
1243 else
1244 mode |= M6812_OP_IDX;
1246 oper->mode = mode;
1247 return 1;
1249 input_line_pointer = old_input_line;
1252 if (mode == M6812_OP_D_IDX_2)
1254 as_bad (_("Invalid indexed indirect mode."));
1255 return -1;
1259 /* If the mode is not known until now, this is either a label
1260 or an indirect address. */
1261 if (mode == M6811_OP_NONE)
1262 mode = M6811_OP_IND16 | M6811_OP_JUMP_REL;
1264 p = input_line_pointer;
1265 while (*p == ' ' || *p == '\t')
1266 p++;
1267 input_line_pointer = p;
1268 oper->mode = mode;
1270 return 1;
1273 #define M6812_AUTO_INC_DEC (M6812_PRE_INC | M6812_PRE_DEC \
1274 | M6812_POST_INC | M6812_POST_DEC)
1276 /* Checks that the number 'num' fits for a given mode. */
1277 static int
1278 check_range (num, mode)
1279 long num;
1280 int mode;
1282 /* Auto increment and decrement are ok for [-8..8] without 0. */
1283 if (mode & M6812_AUTO_INC_DEC)
1284 return (num != 0 && num <= 8 && num >= -8);
1286 /* The 68HC12 supports 5, 9 and 16-bit offsets. */
1287 if (mode & (M6812_INDEXED_IND | M6812_INDEXED | M6812_OP_IDX))
1288 mode = M6811_OP_IND16;
1290 if (mode & M6812_OP_JUMP_REL16)
1291 mode = M6811_OP_IND16;
1293 mode &= ~M6811_OP_BRANCH;
1294 switch (mode)
1296 case M6811_OP_IX:
1297 case M6811_OP_IY:
1298 case M6811_OP_DIRECT:
1299 return (num >= 0 && num <= 255) ? 1 : 0;
1301 case M6811_OP_BITMASK:
1302 case M6811_OP_IMM8:
1303 case M6812_OP_PAGE:
1304 return (((num & 0xFFFFFF00) == 0) || ((num & 0xFFFFFF00) == 0xFFFFFF00))
1305 ? 1 : 0;
1307 case M6811_OP_JUMP_REL:
1308 return (num >= -128 && num <= 127) ? 1 : 0;
1310 case M6811_OP_IND16:
1311 case M6811_OP_IND16 | M6812_OP_PAGE:
1312 case M6811_OP_IMM16:
1313 return (((num & 0xFFFF0000) == 0) || ((num & 0xFFFF0000) == 0xFFFF0000))
1314 ? 1 : 0;
1316 case M6812_OP_IBCC_MARKER:
1317 case M6812_OP_TBCC_MARKER:
1318 case M6812_OP_DBCC_MARKER:
1319 return (num >= -256 && num <= 255) ? 1 : 0;
1321 case M6812_OP_TRAP_ID:
1322 return ((num >= 0x30 && num <= 0x39)
1323 || (num >= 0x40 && num <= 0x0ff)) ? 1 : 0;
1325 default:
1326 return 0;
1330 /* Gas fixup generation. */
1332 /* Put a 1 byte expression described by 'oper'. If this expression contains
1333 unresolved symbols, generate an 8-bit fixup. */
1334 static void
1335 fixup8 (oper, mode, opmode)
1336 expressionS *oper;
1337 int mode;
1338 int opmode;
1340 char *f;
1342 f = frag_more (1);
1344 if (oper->X_op == O_constant)
1346 if (mode & M6812_OP_TRAP_ID
1347 && !check_range (oper->X_add_number, M6812_OP_TRAP_ID))
1349 static char trap_id_warn_once = 0;
1351 as_bad (_("Trap id `%ld' is out of range."), oper->X_add_number);
1352 if (trap_id_warn_once == 0)
1354 trap_id_warn_once = 1;
1355 as_bad (_("Trap id must be within [0x30..0x39] or [0x40..0xff]."));
1359 if (!(mode & M6812_OP_TRAP_ID)
1360 && !check_range (oper->X_add_number, mode))
1362 as_bad (_("Operand out of 8-bit range: `%ld'."), oper->X_add_number);
1364 number_to_chars_bigendian (f, oper->X_add_number & 0x0FF, 1);
1366 else if (oper->X_op != O_register)
1368 if (mode & M6812_OP_TRAP_ID)
1369 as_bad (_("The trap id must be a constant."));
1371 if (mode == M6811_OP_JUMP_REL)
1373 fixS *fixp;
1375 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
1376 oper, true, BFD_RELOC_8_PCREL);
1377 fixp->fx_pcrel_adjust = 1;
1379 else
1381 /* Now create an 8-bit fixup. If there was some %hi or %lo
1382 modifier, generate the reloc accordingly. */
1383 fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
1384 oper, false,
1385 ((opmode & M6811_OP_HIGH_ADDR)
1386 ? BFD_RELOC_M68HC11_HI8
1387 : ((opmode & M6811_OP_LOW_ADDR)
1388 ? BFD_RELOC_M68HC11_LO8
1389 : ((mode & M6812_OP_PAGE)
1390 ? BFD_RELOC_M68HC11_PAGE : BFD_RELOC_8))));
1392 number_to_chars_bigendian (f, 0, 1);
1394 else
1396 as_fatal (_("Operand `%x' not recognized in fixup8."), oper->X_op);
1400 /* Put a 2 byte expression described by 'oper'. If this expression contains
1401 unresolved symbols, generate a 16-bit fixup. */
1402 static void
1403 fixup16 (oper, mode, opmode)
1404 expressionS *oper;
1405 int mode;
1406 int opmode ATTRIBUTE_UNUSED;
1408 char *f;
1410 f = frag_more (2);
1412 if (oper->X_op == O_constant)
1414 if (!check_range (oper->X_add_number, mode))
1416 as_bad (_("Operand out of 16-bit range: `%ld'."),
1417 oper->X_add_number);
1419 number_to_chars_bigendian (f, oper->X_add_number & 0x0FFFF, 2);
1421 else if (oper->X_op != O_register)
1423 fixS *fixp;
1425 /* Now create a 16-bit fixup. */
1426 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 2,
1427 oper,
1428 (mode & M6812_OP_JUMP_REL16 ? true : false),
1429 (mode & M6812_OP_JUMP_REL16
1430 ? BFD_RELOC_16_PCREL
1431 : (mode & M6812_OP_PAGE)
1432 ? BFD_RELOC_M68HC11_LO16 : BFD_RELOC_16));
1433 number_to_chars_bigendian (f, 0, 2);
1434 if (mode & M6812_OP_JUMP_REL16)
1435 fixp->fx_pcrel_adjust = 2;
1437 else
1439 as_fatal (_("Operand `%x' not recognized in fixup16."), oper->X_op);
1443 /* Put a 3 byte expression described by 'oper'. If this expression contains
1444 unresolved symbols, generate a 24-bit fixup. */
1445 static void
1446 fixup24 (oper, mode, opmode)
1447 expressionS *oper;
1448 int mode;
1449 int opmode ATTRIBUTE_UNUSED;
1451 char *f;
1453 f = frag_more (3);
1455 if (oper->X_op == O_constant)
1457 if (!check_range (oper->X_add_number, mode))
1459 as_bad (_("Operand out of 16-bit range: `%ld'."),
1460 oper->X_add_number);
1462 number_to_chars_bigendian (f, oper->X_add_number & 0x0FFFFFF, 3);
1464 else if (oper->X_op != O_register)
1466 fixS *fixp;
1468 /* Now create a 24-bit fixup. */
1469 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 2,
1470 oper, false, BFD_RELOC_M68HC11_24);
1471 number_to_chars_bigendian (f, 0, 3);
1473 else
1475 as_fatal (_("Operand `%x' not recognized in fixup16."), oper->X_op);
1479 /* 68HC11 and 68HC12 code generation. */
1481 /* Translate the short branch/bsr instruction into a long branch. */
1482 static unsigned char
1483 convert_branch (code)
1484 unsigned char code;
1486 if (IS_OPCODE (code, M6812_BSR))
1487 return M6812_JSR;
1488 else if (IS_OPCODE (code, M6811_BSR))
1489 return M6811_JSR;
1490 else if (IS_OPCODE (code, M6811_BRA))
1491 return (current_architecture & cpu6812) ? M6812_JMP : M6811_JMP;
1492 else
1493 as_fatal (_("Unexpected branch conversion with `%x'"), code);
1495 /* Keep gcc happy. */
1496 return M6811_JSR;
1499 /* Start a new insn that contains at least 'size' bytes. Record the
1500 line information of that insn in the dwarf2 debug sections. */
1501 static char *
1502 m68hc11_new_insn (size)
1503 int size;
1505 char *f;
1507 f = frag_more (size);
1509 dwarf2_emit_insn (size);
1511 return f;
1514 /* Builds a jump instruction (bra, bcc, bsr). */
1515 static void
1516 build_jump_insn (opcode, operands, nb_operands, jmp_mode)
1517 struct m68hc11_opcode *opcode;
1518 operand operands[];
1519 int nb_operands;
1520 int jmp_mode;
1522 unsigned char code;
1523 char *f;
1524 unsigned long n;
1525 fragS *frag;
1526 int where;
1528 /* The relative branch convertion is not supported for
1529 brclr and brset. */
1530 assert ((opcode->format & M6811_OP_BITMASK) == 0);
1531 assert (nb_operands == 1);
1532 assert (operands[0].reg1 == REG_NONE && operands[0].reg2 == REG_NONE);
1534 code = opcode->opcode;
1536 n = operands[0].exp.X_add_number;
1538 /* Turn into a long branch:
1539 - when force long branch option (and not for jbcc pseudos),
1540 - when jbcc and the constant is out of -128..127 range,
1541 - when branch optimization is allowed and branch out of range. */
1542 if ((jmp_mode == 0 && flag_force_long_jumps)
1543 || (operands[0].exp.X_op == O_constant
1544 && (!check_range (n, opcode->format) &&
1545 (jmp_mode == 1 || flag_fixed_branchs == 0))))
1547 frag = frag_now;
1548 where = frag_now_fix ();
1550 fix_new (frag_now, frag_now_fix (), 1,
1551 &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
1553 if (code == M6811_BSR || code == M6811_BRA || code == M6812_BSR)
1555 code = convert_branch (code);
1557 f = m68hc11_new_insn (1);
1558 number_to_chars_bigendian (f, code, 1);
1560 else if (current_architecture & cpu6812)
1562 /* 68HC12: translate the bcc into a lbcc. */
1563 f = m68hc11_new_insn (2);
1564 number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1);
1565 number_to_chars_bigendian (f + 1, code, 1);
1566 fixup16 (&operands[0].exp, M6812_OP_JUMP_REL16,
1567 M6812_OP_JUMP_REL16);
1568 return;
1570 else
1572 /* 68HC11: translate the bcc into b!cc +3; jmp <L>. */
1573 f = m68hc11_new_insn (3);
1574 code ^= 1;
1575 number_to_chars_bigendian (f, code, 1);
1576 number_to_chars_bigendian (f + 1, 3, 1);
1577 number_to_chars_bigendian (f + 2, M6811_JMP, 1);
1579 fixup16 (&operands[0].exp, M6811_OP_IND16, M6811_OP_IND16);
1580 return;
1583 /* Branch with a constant that must fit in 8-bits. */
1584 if (operands[0].exp.X_op == O_constant)
1586 if (!check_range (n, opcode->format))
1588 as_bad (_("Operand out of range for a relative branch: `%ld'"),
1591 else if (opcode->format & M6812_OP_JUMP_REL16)
1593 f = m68hc11_new_insn (4);
1594 number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1);
1595 number_to_chars_bigendian (f + 1, code, 1);
1596 number_to_chars_bigendian (f + 2, n & 0x0ffff, 2);
1598 else
1600 f = m68hc11_new_insn (2);
1601 number_to_chars_bigendian (f, code, 1);
1602 number_to_chars_bigendian (f + 1, n & 0x0FF, 1);
1605 else if (opcode->format & M6812_OP_JUMP_REL16)
1607 frag = frag_now;
1608 where = frag_now_fix ();
1610 fix_new (frag_now, frag_now_fix (), 1,
1611 &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
1613 f = m68hc11_new_insn (2);
1614 number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1);
1615 number_to_chars_bigendian (f + 1, code, 1);
1616 fixup16 (&operands[0].exp, M6812_OP_JUMP_REL16, M6812_OP_JUMP_REL16);
1618 else
1620 char *opcode;
1622 frag = frag_now;
1623 where = frag_now_fix ();
1625 fix_new (frag_now, frag_now_fix (), 1,
1626 &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
1628 /* Branch offset must fit in 8-bits, don't do some relax. */
1629 if (jmp_mode == 0 && flag_fixed_branchs)
1631 opcode = m68hc11_new_insn (1);
1632 number_to_chars_bigendian (opcode, code, 1);
1633 fixup8 (&operands[0].exp, M6811_OP_JUMP_REL, M6811_OP_JUMP_REL);
1636 /* bra/bsr made be changed into jmp/jsr. */
1637 else if (code == M6811_BSR || code == M6811_BRA || code == M6812_BSR)
1639 /* Allocate worst case storage. */
1640 opcode = m68hc11_new_insn (3);
1641 number_to_chars_bigendian (opcode, code, 1);
1642 number_to_chars_bigendian (opcode + 1, 0, 1);
1643 frag_variant (rs_machine_dependent, 1, 1,
1644 ENCODE_RELAX (STATE_PC_RELATIVE, STATE_UNDF),
1645 operands[0].exp.X_add_symbol, (offsetT) n,
1646 opcode);
1648 else if (current_architecture & cpu6812)
1650 opcode = m68hc11_new_insn (2);
1651 number_to_chars_bigendian (opcode, code, 1);
1652 number_to_chars_bigendian (opcode + 1, 0, 1);
1653 frag_var (rs_machine_dependent, 2, 2,
1654 ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_UNDF),
1655 operands[0].exp.X_add_symbol, (offsetT) n, opcode);
1657 else
1659 opcode = m68hc11_new_insn (2);
1660 number_to_chars_bigendian (opcode, code, 1);
1661 number_to_chars_bigendian (opcode + 1, 0, 1);
1662 frag_var (rs_machine_dependent, 3, 3,
1663 ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_UNDF),
1664 operands[0].exp.X_add_symbol, (offsetT) n, opcode);
1669 /* Builds a dbne/dbeq/tbne/tbeq instruction. */
1670 static void
1671 build_dbranch_insn (opcode, operands, nb_operands, jmp_mode)
1672 struct m68hc11_opcode *opcode;
1673 operand operands[];
1674 int nb_operands;
1675 int jmp_mode;
1677 unsigned char code;
1678 char *f;
1679 unsigned long n;
1681 /* The relative branch convertion is not supported for
1682 brclr and brset. */
1683 assert ((opcode->format & M6811_OP_BITMASK) == 0);
1684 assert (nb_operands == 2);
1685 assert (operands[0].reg1 != REG_NONE);
1687 code = opcode->opcode & 0x0FF;
1689 f = m68hc11_new_insn (1);
1690 number_to_chars_bigendian (f, code, 1);
1692 n = operands[1].exp.X_add_number;
1693 code = operands[0].reg1;
1695 if (operands[0].reg1 == REG_NONE || operands[0].reg1 == REG_CCR
1696 || operands[0].reg1 == REG_PC)
1697 as_bad (_("Invalid register for dbcc/tbcc instruction."));
1699 if (opcode->format & M6812_OP_IBCC_MARKER)
1700 code |= 0x80;
1701 else if (opcode->format & M6812_OP_TBCC_MARKER)
1702 code |= 0x40;
1704 if (!(opcode->format & M6812_OP_EQ_MARKER))
1705 code |= 0x20;
1707 /* Turn into a long branch:
1708 - when force long branch option (and not for jbcc pseudos),
1709 - when jdbcc and the constant is out of -256..255 range,
1710 - when branch optimization is allowed and branch out of range. */
1711 if ((jmp_mode == 0 && flag_force_long_jumps)
1712 || (operands[1].exp.X_op == O_constant
1713 && (!check_range (n, M6812_OP_IBCC_MARKER) &&
1714 (jmp_mode == 1 || flag_fixed_branchs == 0))))
1716 f = frag_more (2);
1717 code ^= 0x20;
1718 number_to_chars_bigendian (f, code, 1);
1719 number_to_chars_bigendian (f + 1, M6812_JMP, 1);
1720 fixup16 (&operands[0].exp, M6811_OP_IND16, M6811_OP_IND16);
1721 return;
1724 /* Branch with a constant that must fit in 9-bits. */
1725 if (operands[1].exp.X_op == O_constant)
1727 if (!check_range (n, M6812_OP_IBCC_MARKER))
1729 as_bad (_("Operand out of range for a relative branch: `%ld'"),
1732 else
1734 if ((long) n < 0)
1735 code |= 0x10;
1737 f = frag_more (2);
1738 number_to_chars_bigendian (f, code, 1);
1739 number_to_chars_bigendian (f + 1, n & 0x0FF, 1);
1742 else
1744 /* Branch offset must fit in 8-bits, don't do some relax. */
1745 if (jmp_mode == 0 && flag_fixed_branchs)
1747 fixup8 (&operands[0].exp, M6811_OP_JUMP_REL, M6811_OP_JUMP_REL);
1750 else
1752 f = frag_more (2);
1753 number_to_chars_bigendian (f, code, 1);
1754 number_to_chars_bigendian (f + 1, 0, 1);
1755 frag_var (rs_machine_dependent, 3, 3,
1756 ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_UNDF),
1757 operands[1].exp.X_add_symbol, (offsetT) n, f);
1762 #define OP_EXTENDED (M6811_OP_PAGE2 | M6811_OP_PAGE3 | M6811_OP_PAGE4)
1764 /* Assemble the post index byte for 68HC12 extended addressing modes. */
1765 static int
1766 build_indexed_byte (op, format, move_insn)
1767 operand *op;
1768 int format ATTRIBUTE_UNUSED;
1769 int move_insn;
1771 unsigned char byte = 0;
1772 char *f;
1773 int mode;
1774 long val;
1776 val = op->exp.X_add_number;
1777 mode = op->mode;
1778 if (mode & M6812_AUTO_INC_DEC)
1780 byte = 0x20;
1781 if (mode & (M6812_POST_INC | M6812_POST_DEC))
1782 byte |= 0x10;
1784 if (op->exp.X_op == O_constant)
1786 if (!check_range (val, mode))
1788 as_bad (_("Increment/decrement value is out of range: `%ld'."),
1789 val);
1791 if (mode & (M6812_POST_INC | M6812_PRE_INC))
1792 byte |= (val - 1) & 0x07;
1793 else
1794 byte |= (8 - ((val) & 7)) | 0x8;
1796 switch (op->reg1)
1798 case REG_NONE:
1799 as_fatal (_("Expecting a register."));
1801 case REG_X:
1802 byte |= 0;
1803 break;
1805 case REG_Y:
1806 byte |= 0x40;
1807 break;
1809 case REG_SP:
1810 byte |= 0x80;
1811 break;
1813 default:
1814 as_bad (_("Invalid register for post/pre increment."));
1815 break;
1818 f = frag_more (1);
1819 number_to_chars_bigendian (f, byte, 1);
1820 return 1;
1823 if (mode & (M6812_OP_IDX | M6812_OP_D_IDX_2))
1825 switch (op->reg1)
1827 case REG_X:
1828 byte = 0;
1829 break;
1831 case REG_Y:
1832 byte = 1;
1833 break;
1835 case REG_SP:
1836 byte = 2;
1837 break;
1839 case REG_PC:
1840 byte = 3;
1841 break;
1843 default:
1844 as_bad (_("Invalid register."));
1845 break;
1847 if (op->exp.X_op == O_constant)
1849 if (!check_range (val, M6812_OP_IDX))
1851 as_bad (_("Offset out of 16-bit range: %ld."), val);
1854 if (move_insn && !(val >= -16 && val <= 15))
1856 as_bad (_("Offset out of 5-bit range for movw/movb insn: %ld."),
1857 val);
1858 return -1;
1861 if (val >= -16 && val <= 15 && !(mode & M6812_OP_D_IDX_2))
1863 byte = byte << 6;
1864 byte |= val & 0x1f;
1865 f = frag_more (1);
1866 number_to_chars_bigendian (f, byte, 1);
1867 return 1;
1869 else if (val >= -256 && val <= 255 && !(mode & M6812_OP_D_IDX_2))
1871 byte = byte << 3;
1872 byte |= 0xe0;
1873 if (val < 0)
1874 byte |= 0x1;
1875 f = frag_more (2);
1876 number_to_chars_bigendian (f, byte, 1);
1877 number_to_chars_bigendian (f + 1, val & 0x0FF, 1);
1878 return 2;
1880 else
1882 byte = byte << 3;
1883 if (mode & M6812_OP_D_IDX_2)
1884 byte |= 0xe3;
1885 else
1886 byte |= 0xe2;
1888 f = frag_more (3);
1889 number_to_chars_bigendian (f, byte, 1);
1890 number_to_chars_bigendian (f + 1, val & 0x0FFFF, 2);
1891 return 3;
1894 if (mode & M6812_OP_D_IDX_2)
1896 byte = (byte << 3) | 0xe3;
1897 f = frag_more (1);
1898 number_to_chars_bigendian (f, byte, 1);
1900 fixup16 (&op->exp, 0, 0);
1902 else if (op->reg1 != REG_PC)
1904 byte = (byte << 3) | 0xe2;
1905 f = frag_more (1);
1906 number_to_chars_bigendian (f, byte, 1);
1908 f = frag_more (2);
1909 fix_new_exp (frag_now, f - frag_now->fr_literal, 2,
1910 &op->exp, false, BFD_RELOC_16);
1911 number_to_chars_bigendian (f, 0, 2);
1913 else
1915 f = frag_more (1);
1916 number_to_chars_bigendian (f, byte, 1);
1917 frag_var (rs_machine_dependent, 2, 2,
1918 ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_UNDF),
1919 op->exp.X_add_symbol,
1920 op->exp.X_add_number, f);
1922 return 3;
1925 if (mode & (M6812_OP_REG | M6812_OP_D_IDX))
1927 if (mode & M6812_OP_D_IDX)
1929 if (op->reg1 != REG_D)
1930 as_bad (_("Expecting register D for indexed indirect mode."));
1931 if (move_insn)
1932 as_bad (_("Indexed indirect mode is not allowed for movb/movw."));
1934 byte = 0xE7;
1936 else
1938 switch (op->reg1)
1940 case REG_A:
1941 byte = 0xE4;
1942 break;
1944 case REG_B:
1945 byte = 0xE5;
1946 break;
1948 default:
1949 as_bad (_("Invalid accumulator register."));
1951 case REG_D:
1952 byte = 0xE6;
1953 break;
1956 switch (op->reg2)
1958 case REG_X:
1959 break;
1961 case REG_Y:
1962 byte |= (1 << 3);
1963 break;
1965 case REG_SP:
1966 byte |= (2 << 3);
1967 break;
1969 case REG_PC:
1970 byte |= (3 << 3);
1971 break;
1973 default:
1974 as_bad (_("Invalid indexed register."));
1975 break;
1977 f = frag_more (1);
1978 number_to_chars_bigendian (f, byte, 1);
1979 return 1;
1982 as_fatal (_("Addressing mode not implemented yet."));
1983 return 0;
1986 /* Assemble the 68HC12 register mode byte. */
1987 static int
1988 build_reg_mode (op, format)
1989 operand *op;
1990 int format;
1992 unsigned char byte;
1993 char *f;
1995 if (format & M6812_OP_SEX_MARKER
1996 && op->reg1 != REG_A && op->reg1 != REG_B && op->reg1 != REG_CCR)
1997 as_bad (_("Invalid source register for this instruction, use 'tfr'."));
1998 else if (op->reg1 == REG_NONE || op->reg1 == REG_PC)
1999 as_bad (_("Invalid source register."));
2001 if (format & M6812_OP_SEX_MARKER
2002 && op->reg2 != REG_D
2003 && op->reg2 != REG_X && op->reg2 != REG_Y && op->reg2 != REG_SP)
2004 as_bad (_("Invalid destination register for this instruction, use 'tfr'."));
2005 else if (op->reg2 == REG_NONE || op->reg2 == REG_PC)
2006 as_bad (_("Invalid destination register."));
2008 byte = (op->reg1 << 4) | (op->reg2);
2009 if (format & M6812_OP_EXG_MARKER)
2010 byte |= 0x80;
2012 f = frag_more (1);
2013 number_to_chars_bigendian (f, byte, 1);
2014 return 1;
2017 /* build_insn takes a pointer to the opcode entry in the opcode table,
2018 the array of operand expressions and builds the correspding instruction.
2019 This operation only deals with non relative jumps insn (need special
2020 handling). */
2021 static void
2022 build_insn (opcode, operands, nb_operands)
2023 struct m68hc11_opcode *opcode;
2024 operand operands[];
2025 int nb_operands ATTRIBUTE_UNUSED;
2027 int i;
2028 char *f;
2029 long format;
2030 int move_insn = 0;
2031 fragS *frag;
2032 int where;
2034 /* Put the page code instruction if there is one. */
2035 format = opcode->format;
2037 frag = frag_now;
2038 where = frag_now_fix ();
2040 if (format & M6811_OP_BRANCH)
2041 fix_new (frag, where, 1,
2042 &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
2044 if (format & OP_EXTENDED)
2046 int page_code;
2048 f = m68hc11_new_insn (2);
2049 if (format & M6811_OP_PAGE2)
2050 page_code = M6811_OPCODE_PAGE2;
2051 else if (format & M6811_OP_PAGE3)
2052 page_code = M6811_OPCODE_PAGE3;
2053 else
2054 page_code = M6811_OPCODE_PAGE4;
2056 number_to_chars_bigendian (f, page_code, 1);
2057 f++;
2059 else
2060 f = m68hc11_new_insn (1);
2062 number_to_chars_bigendian (f, opcode->opcode, 1);
2064 i = 0;
2066 /* The 68HC12 movb and movw instructions are special. We have to handle
2067 them in a special way. */
2068 if (format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2))
2070 move_insn = 1;
2071 if (format & M6812_OP_IDX)
2073 build_indexed_byte (&operands[0], format, 1);
2074 i = 1;
2075 format &= ~M6812_OP_IDX;
2077 if (format & M6812_OP_IDX_P2)
2079 build_indexed_byte (&operands[1], format, 1);
2080 i = 0;
2081 format &= ~M6812_OP_IDX_P2;
2085 if (format & (M6811_OP_DIRECT | M6811_OP_IMM8))
2087 fixup8 (&operands[i].exp,
2088 format & (M6811_OP_DIRECT | M6811_OP_IMM8 | M6812_OP_TRAP_ID),
2089 operands[i].mode);
2090 i++;
2092 else if (IS_CALL_SYMBOL (format) && nb_operands == 1)
2094 format &= ~M6812_OP_PAGE;
2095 fixup24 (&operands[i].exp, format & M6811_OP_IND16,
2096 operands[i].mode);
2097 i++;
2099 else if (format & (M6811_OP_IMM16 | M6811_OP_IND16))
2101 fixup16 (&operands[i].exp,
2102 format & (M6811_OP_IMM16 | M6811_OP_IND16 | M6812_OP_PAGE),
2103 operands[i].mode);
2104 i++;
2106 else if (format & (M6811_OP_IX | M6811_OP_IY))
2108 if ((format & M6811_OP_IX) && (operands[0].reg1 != REG_X))
2109 as_bad (_("Invalid indexed register, expecting register X."));
2110 if ((format & M6811_OP_IY) && (operands[0].reg1 != REG_Y))
2111 as_bad (_("Invalid indexed register, expecting register Y."));
2113 fixup8 (&operands[0].exp, M6811_OP_IX, operands[0].mode);
2114 i = 1;
2116 else if (format &
2117 (M6812_OP_IDX | M6812_OP_IDX_2 | M6812_OP_IDX_1
2118 | M6812_OP_D_IDX | M6812_OP_D_IDX_2))
2120 build_indexed_byte (&operands[i], format, move_insn);
2121 i++;
2123 else if (format & M6812_OP_REG && current_architecture & cpu6812)
2125 build_reg_mode (&operands[i], format);
2126 i++;
2128 if (format & M6811_OP_BITMASK)
2130 fixup8 (&operands[i].exp, M6811_OP_BITMASK, operands[i].mode);
2131 i++;
2133 if (format & M6811_OP_JUMP_REL)
2135 fixup8 (&operands[i].exp, M6811_OP_JUMP_REL, operands[i].mode);
2137 else if (format & M6812_OP_IND16_P2)
2139 fixup16 (&operands[1].exp, M6811_OP_IND16, operands[1].mode);
2141 if (format & M6812_OP_PAGE)
2143 fixup8 (&operands[i].exp, M6812_OP_PAGE, operands[i].mode);
2147 /* Opcode identification and operand analysis. */
2149 /* find() gets a pointer to an entry in the opcode table. It must look at all
2150 opcodes with the same name and use the operands to choose the correct
2151 opcode. Returns the opcode pointer if there was a match and 0 if none. */
2152 static struct m68hc11_opcode *
2153 find (opc, operands, nb_operands)
2154 struct m68hc11_opcode_def *opc;
2155 operand operands[];
2156 int nb_operands;
2158 int i, match, pos;
2159 struct m68hc11_opcode *opcode;
2160 struct m68hc11_opcode *op_indirect;
2162 op_indirect = 0;
2163 opcode = opc->opcode;
2165 /* Now search the opcode table table for one with operands
2166 that matches what we've got. We're only done if the operands matched so
2167 far AND there are no more to check. */
2168 for (pos = match = 0; match == 0 && pos < opc->nb_modes; pos++, opcode++)
2170 int poss_indirect = 0;
2171 long format = opcode->format;
2172 int expect;
2174 expect = 0;
2175 if (opcode->format & M6811_OP_MASK)
2176 expect++;
2177 if (opcode->format & M6811_OP_BITMASK)
2178 expect++;
2179 if (opcode->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
2180 expect++;
2181 if (opcode->format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2))
2182 expect++;
2183 if ((opcode->format & M6812_OP_PAGE)
2184 && (!IS_CALL_SYMBOL (opcode->format) || nb_operands == 2))
2185 expect++;
2187 for (i = 0; expect == nb_operands && i < nb_operands; i++)
2189 int mode = operands[i].mode;
2191 if (mode & M6811_OP_IMM16)
2193 if (format &
2194 (M6811_OP_IMM8 | M6811_OP_IMM16 | M6811_OP_BITMASK))
2195 continue;
2196 break;
2198 if (mode == M6811_OP_DIRECT)
2200 if (format & M6811_OP_DIRECT)
2201 continue;
2203 /* If the operand is a page 0 operand, remember a
2204 possible <abs-16> addressing mode. We mark
2205 this and continue to check other operands. */
2206 if (format & M6811_OP_IND16
2207 && flag_strict_direct_addressing && op_indirect == 0)
2209 poss_indirect = 1;
2210 continue;
2212 break;
2214 if (mode & M6811_OP_IND16)
2216 if (i == 0 && (format & M6811_OP_IND16) != 0)
2217 continue;
2218 if (i != 0 && (format & M6812_OP_PAGE) != 0)
2219 continue;
2220 if (i != 0 && (format & M6812_OP_IND16_P2) != 0)
2221 continue;
2222 if (i == 0 && (format & M6811_OP_BITMASK))
2223 break;
2225 if (mode & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
2227 if (format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
2228 continue;
2230 if (mode & M6812_OP_REG)
2232 if (i == 0
2233 && (format & M6812_OP_REG)
2234 && (operands[i].reg2 == REG_NONE))
2235 continue;
2236 if (i == 0
2237 && (format & M6812_OP_REG)
2238 && (format & M6812_OP_REG_2)
2239 && (operands[i].reg2 != REG_NONE))
2240 continue;
2241 if (i == 0
2242 && (format & M6812_OP_IDX)
2243 && (operands[i].reg2 != REG_NONE))
2244 continue;
2245 if (i == 0
2246 && (format & M6812_OP_IDX)
2247 && (format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2)))
2248 continue;
2249 if (i == 1
2250 && (format & M6812_OP_IDX_P2))
2251 continue;
2252 break;
2254 if (mode & M6812_OP_IDX)
2256 if (format & M6811_OP_IX && operands[i].reg1 == REG_X)
2257 continue;
2258 if (format & M6811_OP_IY && operands[i].reg1 == REG_Y)
2259 continue;
2260 if (i == 0
2261 && format & (M6812_OP_IDX | M6812_OP_IDX_1 | M6812_OP_IDX_2)
2262 && (operands[i].reg1 == REG_X
2263 || operands[i].reg1 == REG_Y
2264 || operands[i].reg1 == REG_SP
2265 || operands[i].reg1 == REG_PC))
2266 continue;
2267 if (i == 1 && format & M6812_OP_IDX_P2)
2268 continue;
2270 if (mode & format & (M6812_OP_D_IDX | M6812_OP_D_IDX_2))
2272 if (i == 0)
2273 continue;
2275 if (mode & M6812_AUTO_INC_DEC)
2277 if (i == 0
2278 && format & (M6812_OP_IDX | M6812_OP_IDX_1 |
2279 M6812_OP_IDX_2))
2280 continue;
2281 if (i == 1 && format & M6812_OP_IDX_P2)
2282 continue;
2284 break;
2286 match = i == nb_operands;
2288 /* Operands are ok but an operand uses page 0 addressing mode
2289 while the insn supports abs-16 mode. Keep a reference to this
2290 insns in case there is no insn supporting page 0 addressing. */
2291 if (match && poss_indirect)
2293 op_indirect = opcode;
2294 match = 0;
2296 if (match)
2297 break;
2300 /* Page 0 addressing is used but not supported by any insn.
2301 If absolute addresses are supported, we use that insn. */
2302 if (match == 0 && op_indirect)
2304 opcode = op_indirect;
2305 match = 1;
2308 if (!match)
2310 return (0);
2313 return opcode;
2316 /* Find the real opcode and its associated operands. We use a progressive
2317 approach here. On entry, 'opc' points to the first opcode in the
2318 table that matches the opcode name in the source line. We try to
2319 isolate an operand, find a possible match in the opcode table.
2320 We isolate another operand if no match were found. The table 'operands'
2321 is filled while operands are recognized.
2323 Returns the opcode pointer that matches the opcode name in the
2324 source line and the associated operands. */
2325 static struct m68hc11_opcode *
2326 find_opcode (opc, operands, nb_operands)
2327 struct m68hc11_opcode_def *opc;
2328 operand operands[];
2329 int *nb_operands;
2331 struct m68hc11_opcode *opcode;
2332 int i;
2334 if (opc->max_operands == 0)
2336 *nb_operands = 0;
2337 return opc->opcode;
2340 for (i = 0; i < opc->max_operands;)
2342 int result;
2344 result = get_operand (&operands[i], i, opc->format);
2345 if (result <= 0)
2346 return 0;
2348 /* Special case where the bitmask of the bclr/brclr
2349 instructions is not introduced by #.
2350 Example: bclr 3,x $80. */
2351 if (i == 1 && (opc->format & M6811_OP_BITMASK)
2352 && (operands[i].mode & M6811_OP_IND16))
2354 operands[i].mode = M6811_OP_IMM16;
2357 i += result;
2358 *nb_operands = i;
2359 if (i >= opc->min_operands)
2361 opcode = find (opc, operands, i);
2362 if (opcode && !(opcode->format & M6812_OP_PAGE))
2363 return opcode;
2365 if (opcode && *input_line_pointer != ',')
2366 return opcode;
2369 if (*input_line_pointer == ',')
2370 input_line_pointer++;
2373 return 0;
2376 #define M6812_XBCC_MARKER (M6812_OP_TBCC_MARKER \
2377 | M6812_OP_DBCC_MARKER \
2378 | M6812_OP_IBCC_MARKER)
2380 /* Gas line assembler entry point. */
2382 /* This is the main entry point for the machine-dependent assembler. str
2383 points to a machine-dependent instruction. This function is supposed to
2384 emit the frags/bytes it assembles to. */
2385 void
2386 md_assemble (str)
2387 char *str;
2389 struct m68hc11_opcode_def *opc;
2390 struct m68hc11_opcode *opcode;
2392 unsigned char *op_start, *save;
2393 unsigned char *op_end;
2394 char name[20];
2395 int nlen = 0;
2396 operand operands[M6811_MAX_OPERANDS];
2397 int nb_operands;
2398 int branch_optimize = 0;
2399 int alias_id = -1;
2401 /* Drop leading whitespace. */
2402 while (*str == ' ')
2403 str++;
2405 /* Find the opcode end and get the opcode in 'name'. The opcode is forced
2406 lower case (the opcode table only has lower case op-codes). */
2407 for (op_start = op_end = (unsigned char *) (str);
2408 *op_end && nlen < 20 && !is_end_of_line[*op_end] && *op_end != ' ';
2409 op_end++)
2411 name[nlen] = TOLOWER (op_start[nlen]);
2412 nlen++;
2414 name[nlen] = 0;
2416 if (nlen == 0)
2418 as_bad (_("No instruction or missing opcode."));
2419 return;
2422 /* Find the opcode definition given its name. */
2423 opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash, name);
2425 /* If it's not recognized, look for 'jbsr' and 'jbxx'. These are
2426 pseudo insns for relative branch. For these branchs, we always
2427 optimize them (turned into absolute branchs) even if --short-branchs
2428 is given. */
2429 if (opc == NULL && name[0] == 'j' && name[1] == 'b')
2431 opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash, &name[1]);
2432 if (opc
2433 && (!(opc->format & M6811_OP_JUMP_REL)
2434 || (opc->format & M6811_OP_BITMASK)))
2435 opc = 0;
2436 if (opc)
2437 branch_optimize = 1;
2440 /* The following test should probably be removed. This is not conform
2441 to Motorola assembler specs. */
2442 if (opc == NULL && flag_mri)
2444 if (*op_end == ' ' || *op_end == '\t')
2446 while (*op_end == ' ' || *op_end == '\t')
2447 op_end++;
2449 if (nlen < 19
2450 && (*op_end &&
2451 (is_end_of_line[op_end[1]]
2452 || op_end[1] == ' ' || op_end[1] == '\t'
2453 || !ISALNUM (op_end[1])))
2454 && (*op_end == 'a' || *op_end == 'b'
2455 || *op_end == 'A' || *op_end == 'B'
2456 || *op_end == 'd' || *op_end == 'D'
2457 || *op_end == 'x' || *op_end == 'X'
2458 || *op_end == 'y' || *op_end == 'Y'))
2460 name[nlen++] = TOLOWER (*op_end++);
2461 name[nlen] = 0;
2462 opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash,
2463 name);
2468 /* Identify a possible instruction alias. There are some on the
2469 68HC12 to emulate a few 68HC11 instructions. */
2470 if (opc == NULL && (current_architecture & cpu6812))
2472 int i;
2474 for (i = 0; i < m68hc12_num_alias; i++)
2475 if (strcmp (m68hc12_alias[i].name, name) == 0)
2477 alias_id = i;
2478 break;
2481 if (opc == NULL && alias_id < 0)
2483 as_bad (_("Opcode `%s' is not recognized."), name);
2484 return;
2486 save = input_line_pointer;
2487 input_line_pointer = op_end;
2489 if (opc)
2491 opc->used++;
2492 opcode = find_opcode (opc, operands, &nb_operands);
2494 else
2495 opcode = 0;
2497 if ((opcode || alias_id >= 0) && !flag_mri)
2499 char *p = input_line_pointer;
2501 while (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r')
2502 p++;
2504 if (*p != '\n' && *p)
2505 as_bad (_("Garbage at end of instruction: `%s'."), p);
2508 input_line_pointer = save;
2510 if (alias_id >= 0)
2512 char *f = m68hc11_new_insn (m68hc12_alias[alias_id].size);
2514 number_to_chars_bigendian (f, m68hc12_alias[alias_id].code1, 1);
2515 if (m68hc12_alias[alias_id].size > 1)
2516 number_to_chars_bigendian (f + 1, m68hc12_alias[alias_id].code2, 1);
2518 return;
2521 /* Opcode is known but does not have valid operands. Print out the
2522 syntax for this opcode. */
2523 if (opcode == 0)
2525 if (flag_print_insn_syntax)
2526 print_insn_format (name);
2528 as_bad (_("Invalid operand for `%s'"), name);
2529 return;
2532 /* Treat dbeq/ibeq/tbeq instructions in a special way. The branch is
2533 relative and must be in the range -256..255 (9-bits). */
2534 if ((opcode->format & M6812_XBCC_MARKER)
2535 && (opcode->format & M6811_OP_JUMP_REL))
2536 build_dbranch_insn (opcode, operands, nb_operands, branch_optimize);
2538 /* Relative jumps instructions are taken care of separately. We have to make
2539 sure that the relative branch is within the range -128..127. If it's out
2540 of range, the instructions are changed into absolute instructions.
2541 This is not supported for the brset and brclr instructions. */
2542 else if ((opcode->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
2543 && !(opcode->format & M6811_OP_BITMASK))
2544 build_jump_insn (opcode, operands, nb_operands, branch_optimize);
2545 else
2546 build_insn (opcode, operands, nb_operands);
2550 /* Pseudo op to control the ELF flags. */
2551 static void
2552 s_m68hc11_mode (x)
2553 int x ATTRIBUTE_UNUSED;
2555 char *name = input_line_pointer, ch;
2557 while (!is_end_of_line[(unsigned char) *input_line_pointer])
2558 input_line_pointer++;
2559 ch = *input_line_pointer;
2560 *input_line_pointer = '\0';
2562 if (strcmp (name, "mshort") == 0)
2564 elf_flags &= ~E_M68HC11_I32;
2566 else if (strcmp (name, "mlong") == 0)
2568 elf_flags |= E_M68HC11_I32;
2570 else if (strcmp (name, "mshort-double") == 0)
2572 elf_flags &= ~E_M68HC11_F64;
2574 else if (strcmp (name, "mlong-double") == 0)
2576 elf_flags |= E_M68HC11_F64;
2578 else
2580 as_warn (_("Invalid mode: %s\n"), name);
2582 *input_line_pointer = ch;
2583 demand_empty_rest_of_line ();
2586 /* Mark the symbols with STO_M68HC12_FAR to indicate the functions
2587 are using 'rtc' for returning. It is necessary to use 'call'
2588 to invoke them. This is also used by the debugger to correctly
2589 find the stack frame. */
2590 static void
2591 s_m68hc11_mark_symbol (mark)
2592 int mark;
2594 char *name;
2595 int c;
2596 symbolS *symbolP;
2597 asymbol *bfdsym;
2598 elf_symbol_type *elfsym;
2602 name = input_line_pointer;
2603 c = get_symbol_end ();
2604 symbolP = symbol_find_or_make (name);
2605 *input_line_pointer = c;
2607 SKIP_WHITESPACE ();
2609 bfdsym = symbol_get_bfdsym (symbolP);
2610 elfsym = elf_symbol_from (bfd_asymbol_bfd (bfdsym), bfdsym);
2612 assert (elfsym);
2614 /* Mark the symbol far (using rtc for function return). */
2615 elfsym->internal_elf_sym.st_other |= mark;
2617 if (c == ',')
2619 input_line_pointer ++;
2621 SKIP_WHITESPACE ();
2623 if (*input_line_pointer == '\n')
2624 c = '\n';
2627 while (c == ',');
2629 demand_empty_rest_of_line ();
2632 static void
2633 s_m68hc11_relax (ignore)
2634 int ignore ATTRIBUTE_UNUSED;
2636 expressionS ex;
2638 expression (&ex);
2640 if (ex.X_op != O_symbol || ex.X_add_number != 0)
2642 as_bad (_("bad .relax format"));
2643 ignore_rest_of_line ();
2644 return;
2647 fix_new_exp (frag_now, frag_now_fix (), 1, &ex, 1,
2648 BFD_RELOC_M68HC11_RL_GROUP);
2650 demand_empty_rest_of_line ();
2654 /* Relocation, relaxation and frag conversions. */
2656 /* PC-relative offsets are relative to the start of the
2657 next instruction. That is, the address of the offset, plus its
2658 size, since the offset is always the last part of the insn. */
2659 long
2660 md_pcrel_from (fixP)
2661 fixS *fixP;
2663 if (fixP->fx_r_type == BFD_RELOC_M68HC11_RL_JUMP)
2664 return 0;
2666 return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
2669 /* If while processing a fixup, a reloc really needs to be created
2670 then it is done here. */
2671 arelent *
2672 tc_gen_reloc (section, fixp)
2673 asection *section;
2674 fixS *fixp;
2676 arelent *reloc;
2678 reloc = (arelent *) xmalloc (sizeof (arelent));
2679 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
2680 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
2681 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
2682 if (fixp->fx_r_type == 0)
2683 reloc->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_16);
2684 else
2685 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
2686 if (reloc->howto == (reloc_howto_type *) NULL)
2688 as_bad_where (fixp->fx_file, fixp->fx_line,
2689 _("Relocation %d is not supported by object file format."),
2690 (int) fixp->fx_r_type);
2691 return NULL;
2694 /* Since we use Rel instead of Rela, encode the vtable entry to be
2695 used in the relocation's section offset. */
2696 if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
2697 reloc->address = fixp->fx_offset;
2699 reloc->addend = 0;
2700 return reloc;
2703 void
2704 md_convert_frag (abfd, sec, fragP)
2705 bfd *abfd ATTRIBUTE_UNUSED;
2706 asection *sec ATTRIBUTE_UNUSED;
2707 fragS *fragP;
2709 fixS *fixp;
2710 long value;
2711 long disp;
2712 char *buffer_address = fragP->fr_literal;
2714 /* Address in object code of the displacement. */
2715 register int object_address = fragP->fr_fix + fragP->fr_address;
2717 buffer_address += fragP->fr_fix;
2719 /* The displacement of the address, from current location. */
2720 value = S_GET_VALUE (fragP->fr_symbol);
2721 disp = (value + fragP->fr_offset) - object_address;
2723 switch (fragP->fr_subtype)
2725 case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE):
2726 fragP->fr_opcode[1] = disp;
2727 break;
2729 case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD):
2730 /* This relax is only for bsr and bra. */
2731 assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
2732 || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
2733 || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
2735 fragP->fr_opcode[0] = convert_branch (fragP->fr_opcode[0]);
2737 fix_new (fragP, fragP->fr_fix - 1, 2,
2738 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
2739 fragP->fr_fix += 1;
2740 break;
2742 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_BYTE):
2743 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_BYTE):
2744 fragP->fr_opcode[1] = disp;
2745 break;
2747 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_WORD):
2748 /* Invert branch. */
2749 fragP->fr_opcode[0] ^= 1;
2750 fragP->fr_opcode[1] = 3; /* Branch offset. */
2751 buffer_address[0] = M6811_JMP;
2752 fix_new (fragP, fragP->fr_fix + 1, 2,
2753 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
2754 fragP->fr_fix += 3;
2755 break;
2757 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_WORD):
2758 /* Translate branch into a long branch. */
2759 fragP->fr_opcode[1] = fragP->fr_opcode[0];
2760 fragP->fr_opcode[0] = M6811_OPCODE_PAGE2;
2762 fixp = fix_new (fragP, fragP->fr_fix, 2,
2763 fragP->fr_symbol, fragP->fr_offset, 1,
2764 BFD_RELOC_16_PCREL);
2765 fixp->fx_pcrel_adjust = 2;
2766 fragP->fr_fix += 2;
2767 break;
2769 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS5):
2770 fragP->fr_opcode[0] = fragP->fr_opcode[0] << 6;
2771 if ((fragP->fr_opcode[0] & 0x0ff) == 0x0c0)
2772 fragP->fr_opcode[0] |= disp & 0x1f;
2773 else
2774 fragP->fr_opcode[0] |= value & 0x1f;
2775 break;
2777 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9):
2778 fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3);
2779 fragP->fr_opcode[0] |= 0xE0;
2780 fix_new (fragP, fragP->fr_fix, 1,
2781 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_8);
2782 fragP->fr_fix += 1;
2783 break;
2785 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16):
2786 fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3);
2787 fragP->fr_opcode[0] |= 0xe2;
2788 if ((fragP->fr_opcode[0] & 0x0ff) == 0x0fa)
2790 fixp = fix_new (fragP, fragP->fr_fix, 2,
2791 fragP->fr_symbol, fragP->fr_offset,
2792 1, BFD_RELOC_16_PCREL);
2793 fixp->fx_pcrel_adjust = 2;
2795 else
2797 fix_new (fragP, fragP->fr_fix, 2,
2798 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
2800 fragP->fr_fix += 2;
2801 break;
2803 case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_BYTE):
2804 if (disp < 0)
2805 fragP->fr_opcode[0] |= 0x10;
2807 fragP->fr_opcode[1] = disp & 0x0FF;
2808 break;
2810 case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_WORD):
2811 /* Invert branch. */
2812 fragP->fr_opcode[0] ^= 0x20;
2813 fragP->fr_opcode[1] = 3; /* Branch offset. */
2814 buffer_address[0] = M6812_JMP;
2815 fix_new (fragP, fragP->fr_fix + 1, 2,
2816 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
2817 fragP->fr_fix += 3;
2818 break;
2820 default:
2821 break;
2825 /* On an ELF system, we can't relax a weak symbol. The weak symbol
2826 can be overridden at final link time by a non weak symbol. We can
2827 relax externally visible symbol because there is no shared library
2828 and such symbol can't be overridden (unless they are weak). */
2829 static int
2830 relaxable_symbol (symbol)
2831 symbolS *symbol;
2833 return ! S_IS_WEAK (symbol);
2836 /* Force truly undefined symbols to their maximum size, and generally set up
2837 the frag list to be relaxed. */
2839 md_estimate_size_before_relax (fragP, segment)
2840 fragS *fragP;
2841 asection *segment;
2843 if (RELAX_LENGTH (fragP->fr_subtype) == STATE_UNDF)
2845 if (S_GET_SEGMENT (fragP->fr_symbol) != segment
2846 || !relaxable_symbol (fragP->fr_symbol))
2848 /* Non-relaxable cases. */
2849 int old_fr_fix;
2850 char *buffer_address;
2852 old_fr_fix = fragP->fr_fix;
2853 buffer_address = fragP->fr_fix + fragP->fr_literal;
2855 switch (RELAX_STATE (fragP->fr_subtype))
2857 case STATE_PC_RELATIVE:
2859 /* This relax is only for bsr and bra. */
2860 assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
2861 || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
2862 || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
2864 if (flag_fixed_branchs)
2865 as_bad_where (fragP->fr_file, fragP->fr_line,
2866 _("bra or bsr with undefined symbol."));
2868 /* The symbol is undefined or in a separate section.
2869 Turn bra into a jmp and bsr into a jsr. The insn
2870 becomes 3 bytes long (instead of 2). A fixup is
2871 necessary for the unresolved symbol address. */
2872 fragP->fr_opcode[0] = convert_branch (fragP->fr_opcode[0]);
2874 fix_new (fragP, fragP->fr_fix - 1, 2, fragP->fr_symbol,
2875 fragP->fr_offset, 0, BFD_RELOC_16);
2876 fragP->fr_fix++;
2877 break;
2879 case STATE_CONDITIONAL_BRANCH:
2880 assert (current_architecture & cpu6811);
2882 fragP->fr_opcode[0] ^= 1; /* Reverse sense of branch. */
2883 fragP->fr_opcode[1] = 3; /* Skip next jmp insn (3 bytes). */
2885 /* Don't use fr_opcode[2] because this may be
2886 in a different frag. */
2887 buffer_address[0] = M6811_JMP;
2889 fragP->fr_fix++;
2890 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
2891 fragP->fr_offset, 0, BFD_RELOC_16);
2892 fragP->fr_fix += 2;
2893 break;
2895 case STATE_INDEXED_OFFSET:
2896 assert (current_architecture & cpu6812);
2898 /* Switch the indexed operation to 16-bit mode. */
2899 fragP->fr_opcode[0] = fragP->fr_opcode[0] << 3;
2900 fragP->fr_opcode[0] |= 0xe2;
2901 fragP->fr_fix++;
2902 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
2903 fragP->fr_offset, 0, BFD_RELOC_16);
2904 fragP->fr_fix++;
2905 break;
2907 case STATE_XBCC_BRANCH:
2908 assert (current_architecture & cpu6812);
2910 fragP->fr_opcode[0] ^= 0x20; /* Reverse sense of branch. */
2911 fragP->fr_opcode[1] = 3; /* Skip next jmp insn (3 bytes). */
2913 /* Don't use fr_opcode[2] because this may be
2914 in a different frag. */
2915 buffer_address[0] = M6812_JMP;
2917 fragP->fr_fix++;
2918 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
2919 fragP->fr_offset, 0, BFD_RELOC_16);
2920 fragP->fr_fix += 2;
2921 break;
2923 case STATE_CONDITIONAL_BRANCH_6812:
2924 assert (current_architecture & cpu6812);
2926 /* Translate into a lbcc branch. */
2927 fragP->fr_opcode[1] = fragP->fr_opcode[0];
2928 fragP->fr_opcode[0] = M6811_OPCODE_PAGE2;
2930 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
2931 fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
2932 fragP->fr_fix += 2;
2933 break;
2935 default:
2936 as_fatal (_("Subtype %d is not recognized."), fragP->fr_subtype);
2938 frag_wane (fragP);
2940 /* Return the growth in the fixed part of the frag. */
2941 return fragP->fr_fix - old_fr_fix;
2944 /* Relaxable cases. */
2945 switch (RELAX_STATE (fragP->fr_subtype))
2947 case STATE_PC_RELATIVE:
2948 /* This relax is only for bsr and bra. */
2949 assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
2950 || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
2951 || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
2953 fragP->fr_subtype = ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE);
2954 break;
2956 case STATE_CONDITIONAL_BRANCH:
2957 assert (current_architecture & cpu6811);
2959 fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH,
2960 STATE_BYTE);
2961 break;
2963 case STATE_INDEXED_OFFSET:
2964 assert (current_architecture & cpu6812);
2966 fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_OFFSET,
2967 STATE_BITS5);
2968 break;
2970 case STATE_XBCC_BRANCH:
2971 assert (current_architecture & cpu6812);
2973 fragP->fr_subtype = ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_BYTE);
2974 break;
2976 case STATE_CONDITIONAL_BRANCH_6812:
2977 assert (current_architecture & cpu6812);
2979 fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812,
2980 STATE_BYTE);
2981 break;
2985 if (fragP->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))
2986 as_fatal (_("Subtype %d is not recognized."), fragP->fr_subtype);
2988 /* Return the size of the variable part of the frag. */
2989 return md_relax_table[fragP->fr_subtype].rlx_length;
2992 /* See whether we need to force a relocation into the output file. */
2994 tc_m68hc11_force_relocation (fixP)
2995 fixS * fixP;
2997 switch (fixP->fx_r_type)
2999 case BFD_RELOC_VTABLE_INHERIT:
3000 case BFD_RELOC_VTABLE_ENTRY:
3001 case BFD_RELOC_M68HC11_RL_GROUP:
3002 return 1;
3004 default:
3005 break;
3008 return S_FORCE_RELOC (fixP->fx_addsy);
3011 /* Here we decide which fixups can be adjusted to make them relative
3012 to the beginning of the section instead of the symbol. Basically
3013 we need to make sure that the linker relaxation is done
3014 correctly, so in some cases we force the original symbol to be
3015 used. */
3017 tc_m68hc11_fix_adjustable (fixP)
3018 fixS *fixP;
3020 switch (fixP->fx_r_type)
3022 /* For the linker relaxation to work correctly, these relocs
3023 need to be on the symbol itself. */
3024 case BFD_RELOC_16:
3025 case BFD_RELOC_LO16:
3026 case BFD_RELOC_M68HC11_RL_JUMP:
3027 case BFD_RELOC_M68HC11_RL_GROUP:
3028 case BFD_RELOC_VTABLE_INHERIT:
3029 case BFD_RELOC_VTABLE_ENTRY:
3030 return 0;
3032 case BFD_RELOC_32:
3033 default:
3034 return 1;
3038 void
3039 md_apply_fix3 (fixP, valP, seg)
3040 fixS *fixP;
3041 valueT *valP;
3042 segT seg ATTRIBUTE_UNUSED;
3044 char *where;
3045 long value = * valP;
3046 int op_type;
3048 if (fixP->fx_addsy == (symbolS *) NULL)
3049 fixP->fx_done = 1;
3051 /* We don't actually support subtracting a symbol. */
3052 if (fixP->fx_subsy != (symbolS *) NULL)
3053 as_bad_where (fixP->fx_file, fixP->fx_line, _("Expression too complex."));
3055 op_type = fixP->fx_r_type;
3057 /* Patch the instruction with the resolved operand. Elf relocation
3058 info will also be generated to take care of linker/loader fixups.
3059 The 68HC11 addresses only 64Kb, we are only concerned by 8 and 16-bit
3060 relocs. BFD_RELOC_8 is basically used for .page0 access (the linker
3061 will warn for overflows). BFD_RELOC_8_PCREL should not be generated
3062 because it's either resolved or turned out into non-relative insns (see
3063 relax table, bcc, bra, bsr transformations)
3065 The BFD_RELOC_32 is necessary for the support of --gstabs. */
3066 where = fixP->fx_frag->fr_literal + fixP->fx_where;
3068 switch (fixP->fx_r_type)
3070 case BFD_RELOC_32:
3071 bfd_putb32 ((bfd_vma) value, (unsigned char *) where);
3072 break;
3074 case BFD_RELOC_24:
3075 case BFD_RELOC_M68HC11_24:
3076 bfd_putb16 ((bfd_vma) (value & 0x0ffff), (unsigned char *) where);
3077 ((bfd_byte*) where)[2] = ((value >> 16) & 0x0ff);
3078 break;
3080 case BFD_RELOC_16:
3081 case BFD_RELOC_16_PCREL:
3082 case BFD_RELOC_M68HC11_LO16:
3083 bfd_putb16 ((bfd_vma) value, (unsigned char *) where);
3084 if (value < -65537 || value > 65535)
3085 as_bad_where (fixP->fx_file, fixP->fx_line,
3086 _("Value out of 16-bit range."));
3087 break;
3089 case BFD_RELOC_M68HC11_HI8:
3090 value = value >> 8;
3091 /* Fall through. */
3093 case BFD_RELOC_M68HC11_LO8:
3094 case BFD_RELOC_8:
3095 case BFD_RELOC_M68HC11_PAGE:
3096 #if 0
3097 bfd_putb8 ((bfd_vma) value, (unsigned char *) where);
3098 #endif
3099 ((bfd_byte *) where)[0] = (bfd_byte) value;
3100 break;
3102 case BFD_RELOC_8_PCREL:
3103 #if 0
3104 bfd_putb8 ((bfd_vma) value, (unsigned char *) where);
3105 #endif
3106 ((bfd_byte *) where)[0] = (bfd_byte) value;
3108 if (value < -128 || value > 127)
3109 as_bad_where (fixP->fx_file, fixP->fx_line,
3110 _("Value %ld too large for 8-bit PC-relative branch."),
3111 value);
3112 break;
3114 case BFD_RELOC_M68HC11_3B:
3115 if (value <= 0 || value > 8)
3116 as_bad_where (fixP->fx_file, fixP->fx_line,
3117 _("Auto increment/decrement offset '%ld' is out of range."),
3118 value);
3119 if (where[0] & 0x8)
3120 value = 8 - value;
3121 else
3122 value--;
3124 where[0] = where[0] | (value & 0x07);
3125 break;
3127 case BFD_RELOC_M68HC11_RL_JUMP:
3128 case BFD_RELOC_M68HC11_RL_GROUP:
3129 case BFD_RELOC_VTABLE_INHERIT:
3130 case BFD_RELOC_VTABLE_ENTRY:
3131 fixP->fx_done = 0;
3132 return;
3134 default:
3135 as_fatal (_("Line %d: unknown relocation type: 0x%x."),
3136 fixP->fx_line, fixP->fx_r_type);
3140 /* Set the ELF specific flags. */
3141 void
3142 m68hc11_elf_final_processing ()
3144 elf_elfheader (stdoutput)->e_flags &= ~EF_M68HC11_ABI;
3145 elf_elfheader (stdoutput)->e_flags |= elf_flags;