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)
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. */
24 #include "safe-ctype.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. */
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. */
74 These insns are translated into b!cc +3 jmp L. */
75 {(127), (-128), 0, ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
, STATE_WORD
)},
80 /* Relax for bsr <L> and bra <L>.
81 These insns are translated into jsr and jmp. */
82 {(127), (-128), 0, ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_WORD
)},
87 /* Relax for indexed offset: 5-bits, 9-bits, 16-bits. */
88 {(15), (-16), 0, ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS9
)},
89 {(255), (-256), 1, ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS16
)},
93 /* Relax for dbeq/ibeq/tbeq r,<L>:
94 These insns are translated into db!cc +3 jmp L. */
95 {(255), (-256), 0, ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_WORD
)},
100 /* Relax for bcc <L> on 68HC12.
101 These insns are translated into lbcc <L>. */
102 {(127), (-128), 0, ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
, STATE_WORD
)},
109 /* 68HC11 and 68HC12 registers. They are numbered according to the 68HC12. */
110 typedef enum register_id
{
122 typedef struct operand
{
129 struct m68hc11_opcode_def
{
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
{
146 static alias alias_opcodes
[] = {
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:
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
216 static short flag_strict_direct_addressing
= 1;
218 /* When an opcode has invalid operand, print out the syntax of the opcode
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
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. */
260 {"fcc", stringer
, 1},
263 /* Dwarf2 support for Gcc. */
264 {"file", (void (*) PARAMS ((int))) dwarf2_directive_file
, 0},
265 {"loc", dwarf2_directive_loc
, 0},
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
},
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. */
316 m68hc11_arch_format ()
318 get_default_target ();
319 if (current_architecture
& cpu6811
)
320 return "elf32-m68hc11";
322 return "elf32-m68hc12";
325 enum bfd_architecture
328 get_default_target ();
329 if (current_architecture
& cpu6811
)
330 return bfd_arch_m68hc11
;
332 return bfd_arch_m68hc12
;
341 /* Listing header selected according to cpu. */
343 m68hc11_listing_header ()
345 if (current_architecture
& cpu6811
)
346 return "M68HC11 GAS ";
348 return "M68HC12 GAS ";
352 md_show_usage (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. */
373 get_default_target ()
375 const bfd_target
*target
;
378 if (current_architecture
!= 0)
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";
397 as_bad (_("Default target `%s' is not supported."), target
->name
);
403 m68hc11_print_statistics (file
)
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)
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",
422 opc
->min_operands
, opc
->max_operands
, opc
->format
, opc
->used
);
427 md_parse_option (c
, arg
)
431 get_default_target ();
434 /* -S means keep external to 2 bit offset rather than 16 bit one. */
435 case OPTION_SHORT_BRANCHS
:
437 flag_fixed_branchs
= 1;
440 case OPTION_FORCE_LONG_BRANCH
:
441 flag_force_long_jumps
= 1;
444 case OPTION_PRINT_INSN_SYNTAX
:
445 flag_print_insn_syntax
= 1;
448 case OPTION_PRINT_OPCODES
:
449 flag_print_opcodes
= 1;
452 case OPTION_STRICT_DIRECT_MODE
:
453 flag_strict_direct_addressing
= 0;
456 case OPTION_GENERATE_EXAMPLE
:
457 flag_print_opcodes
= 2;
461 if (strcasecmp (arg
, "68hc11") == 0)
462 current_architecture
= cpu6811
;
463 else if (strcasecmp (arg
, "68hc12") == 0)
464 current_architecture
= cpu6812
;
466 as_bad (_("Option `%s' is not recognized."), arg
);
477 md_undefined_symbol (name
)
478 char *name ATTRIBUTE_UNUSED
;
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. */
491 md_atof (type
, litP
, sizeP
)
497 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
498 LITTLENUM_TYPE
*wordP
;
529 return _("Bad call to MD_ATOF()");
531 t
= atof_ieee (input_line_pointer
, type
, words
);
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
);
545 md_section_align (seg
, addr
)
549 int align
= bfd_get_section_alignment (stdoutput
, seg
);
550 return ((addr
+ (1 << align
) - 1) & (-1 << align
));
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). */
571 char *prev_name
= "";
572 struct m68hc11_opcode
*opcodes
;
573 struct m68hc11_opcode_def
*opc
= 0;
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
*
584 m68hc11_sorted_opcodes
= opcodes
;
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
))
596 opcodes
[num_opcodes
] = m68hc11_opcodes
[i
];
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
;
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
++)
623 if (strcmp (prev_name
, opcodes
->name
))
625 prev_name
= (char *) opcodes
->name
;
629 opc
->min_operands
= 100;
630 opc
->max_operands
= 0;
632 opc
->opcode
= opcodes
;
634 hash_insert (m68hc11_hash
, opcodes
->name
, (char *) opc
);
637 opc
->format
|= opcodes
->format
;
639 /* See how many operands this opcode needs. */
641 if (opcodes
->format
& M6811_OP_MASK
)
643 if (opcodes
->format
& M6811_OP_BITMASK
)
645 if (opcodes
->format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
647 if (opcodes
->format
& (M6812_OP_IND16_P2
| M6812_OP_IDX_P2
))
649 /* Special case for call instruction. */
650 if ((opcodes
->format
& M6812_OP_PAGE
)
651 && !(opcodes
->format
& M6811_OP_IND16
))
654 if (expect
< opc
->min_operands
)
655 opc
->min_operands
= expect
;
656 if (IS_CALL_SYMBOL (opcodes
->format
))
658 if (expect
> opc
->max_operands
)
659 opc
->max_operands
= expect
;
662 m68hc11_nb_opcode_defs
= opc
- m68hc11_opcode_defs
;
664 if (flag_print_opcodes
)
666 print_opcode_list ();
672 m68hc11_init_after_args ()
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. */
682 print_opcode_format (opcode
, example
)
683 struct m68hc11_opcode
*opcode
;
686 static char buf
[128];
687 int format
= opcode
->format
;
692 if (format
& M6811_OP_IMM8
)
695 sprintf (p
, "#%d", rand () & 0x0FF);
697 strcpy (p
, _("#<imm8>"));
701 if (format
& M6811_OP_IMM16
)
704 sprintf (p
, "#%d", rand () & 0x0FFFF);
706 strcpy (p
, _("#<imm16>"));
710 if (format
& M6811_OP_IX
)
713 sprintf (p
, "%d,X", rand () & 0x0FF);
715 strcpy (p
, _("<imm8>,X"));
719 if (format
& M6811_OP_IY
)
722 sprintf (p
, "%d,X", rand () & 0x0FF);
724 strcpy (p
, _("<imm8>,X"));
728 if (format
& M6812_OP_IDX
)
731 sprintf (p
, "%d,X", rand () & 0x0FF);
737 if (format
& M6812_OP_PAGE
)
740 sprintf (p
, ", %d", rand () & 0x0FF);
742 strcpy (p
, ", <page>");
746 if (format
& M6811_OP_DIRECT
)
749 sprintf (p
, "*Z%d", rand () & 0x0FF);
751 strcpy (p
, _("*<abs8>"));
755 if (format
& M6811_OP_BITMASK
)
761 sprintf (p
, "#$%02x", rand () & 0x0FF);
763 strcpy (p
, _("#<mask>"));
766 if (format
& M6811_OP_JUMP_REL
)
770 if (format
& M6811_OP_IND16
)
773 sprintf (p
, _("symbol%d"), rand () & 0x0FF);
775 strcpy (p
, _("<abs>"));
780 if (format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
784 if (format
& M6811_OP_BITMASK
)
786 sprintf (p
, ".+%d", rand () & 0x7F);
790 sprintf (p
, "L%d", rand () & 0x0FF);
794 strcpy (p
, _("<label>"));
800 /* Prints the list of instructions with the possible operands. */
805 char *prev_name
= "";
806 struct m68hc11_opcode
*opcodes
;
807 int example
= flag_print_opcodes
== 2;
810 printf (_("# Example of `%s' instructions\n\t.sect .text\n_start:\n"),
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
818 for (i
= 0; i
< num_opcodes
; i
++, opcodes
++)
820 char *fmt
= print_opcode_format (opcodes
, example
);
824 printf ("L%d:\t", i
);
825 printf ("%s %s\n", opcodes
->name
, fmt
);
829 if (strcmp (prev_name
, opcodes
->name
))
834 printf ("%-5.5s ", opcodes
->name
);
835 prev_name
= (char *) opcodes
->name
;
838 printf (" [%s]", fmt
);
844 /* Print the instruction format. This operation is called when some
845 instruction is not correct. Instruction format is printed as an
848 print_insn_format (name
)
851 struct m68hc11_opcode_def
*opc
;
852 struct m68hc11_opcode
*opcode
;
855 opc
= (struct m68hc11_opcode_def
*) hash_find (m68hc11_hash
, name
);
858 as_bad (_("Instruction `%s' is not recognized."), name
);
861 opcode
= opc
->opcode
;
863 as_bad (_("Instruction formats for `%s':"), name
);
868 fmt
= print_opcode_format (opcode
, 0);
869 sprintf (buf
, "\t%-5.5s %s", opcode
->name
, fmt
);
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. */
882 reg_name_search (name
)
885 if (strcasecmp (name
, "x") == 0 || strcasecmp (name
, "ix") == 0)
887 if (strcasecmp (name
, "y") == 0 || strcasecmp (name
, "iy") == 0)
889 if (strcasecmp (name
, "a") == 0)
891 if (strcasecmp (name
, "b") == 0)
893 if (strcasecmp (name
, "d") == 0)
895 if (strcasecmp (name
, "sp") == 0)
897 if (strcasecmp (name
, "pc") == 0)
899 if (strcasecmp (name
, "ccr") == 0)
909 while (*p
== ' ' || *p
== '\t')
915 /* Check the string at input_line_pointer
916 to see if it is a valid register name. */
920 register_id reg_number
;
921 char c
, *p
= input_line_pointer
;
923 if (!is_name_beginner (*p
++))
926 while (is_part_of_name (*p
++))
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
)
940 input_line_pointer
= p
;
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 */
965 get_operand (oper
, which
, opmode
)
970 char *p
= input_line_pointer
;
974 oper
->exp
.X_op
= O_absent
;
975 oper
->reg1
= REG_NONE
;
976 oper
->reg2
= REG_NONE
;
977 mode
= M6811_OP_NONE
;
981 if (*p
== 0 || *p
== '\n' || *p
== '\r')
983 input_line_pointer
= p
;
987 if (*p
== '*' && (opmode
& (M6811_OP_DIRECT
| M6811_OP_IND16
)))
989 mode
= M6811_OP_DIRECT
;
994 if (!(opmode
& (M6811_OP_IMM8
| M6811_OP_IMM16
| M6811_OP_BITMASK
)))
996 as_bad (_("Immediate operand is not allowed for operand %d."),
1001 mode
= M6811_OP_IMM16
;
1003 if (strncmp (p
, "%hi", 3) == 0)
1006 mode
|= M6811_OP_HIGH_ADDR
;
1008 else if (strncmp (p
, "%lo", 3) == 0)
1011 mode
|= M6811_OP_LOW_ADDR
;
1014 else if (*p
== '.' && (p
[1] == '+' || p
[1] == '-'))
1017 mode
= M6811_OP_JUMP_REL
;
1021 if (current_architecture
& cpu6811
)
1022 as_bad (_("Indirect indexed addressing is not valid for 68HC11."));
1025 mode
= M6812_OP_D_IDX
;
1026 p
= skip_whites (p
);
1028 else if (*p
== ',') /* Special handling of ,x and ,y. */
1031 input_line_pointer
= p
;
1033 reg
= register_name ();
1034 if (reg
!= REG_NONE
)
1037 oper
->exp
.X_op
= O_constant
;
1038 oper
->exp
.X_add_number
= 0;
1039 oper
->mode
= M6812_OP_IDX
;
1042 as_bad (_("Spurious `,' or bad indirect register addressing mode."));
1045 input_line_pointer
= p
;
1047 if (mode
== M6811_OP_NONE
|| mode
== M6812_OP_D_IDX
)
1048 reg
= register_name ();
1052 if (reg
!= REG_NONE
)
1054 p
= skip_whites (input_line_pointer
);
1055 if (*p
== ']' && mode
== M6812_OP_D_IDX
)
1058 (_("Missing second register or offset for indexed-indirect mode."));
1063 oper
->mode
= mode
| M6812_OP_REG
;
1066 if (mode
== M6812_OP_D_IDX
)
1068 as_bad (_("Missing second register for indexed-indirect mode."));
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
)
1084 as_bad (_("Missing `]' to close indexed-indirect mode."));
1088 oper
->mode
= M6812_OP_D_IDX
;
1090 input_line_pointer
= p
;
1098 /* In MRI mode, isolate the operand because we can't distinguish
1099 operands from comments. */
1104 p
= skip_whites (p
);
1105 while (*p
&& *p
!= ' ' && *p
!= '\t')
1114 /* Parse as an expression. */
1115 expression (&oper
->exp
);
1124 expression (&oper
->exp
);
1127 if (oper
->exp
.X_op
== O_illegal
)
1129 as_bad (_("Illegal operand."));
1132 else if (oper
->exp
.X_op
== O_absent
)
1134 as_bad (_("Missing operand."));
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
);
1147 int possible_mode
= M6811_OP_NONE
;
1148 char *old_input_line
;
1153 /* 68HC12 pre increment or decrement. */
1154 if (mode
== M6811_OP_NONE
)
1158 possible_mode
= M6812_PRE_DEC
;
1163 possible_mode
= M6812_PRE_INC
;
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
);
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"));
1189 if (which
== 0 && opmode
& M6812_OP_IDX_P2
1190 && reg
!= REG_X
&& reg
!= REG_Y
1191 && reg
!= REG_PC
&& reg
!= REG_SP
)
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."));
1203 if (mode
== M6812_OP_D_IDX
)
1205 p
= skip_whites (input_line_pointer
);
1208 as_bad (_("Missing `]' to close register indirect operand."));
1211 input_line_pointer
= p
;
1213 oper
->mode
= M6812_OP_D_IDX_2
;
1216 if (reg
!= REG_NONE
)
1219 if (mode
== M6811_OP_NONE
)
1221 p
= input_line_pointer
;
1224 mode
= M6812_POST_DEC
;
1226 if (current_architecture
& cpu6811
)
1228 (_("Post-decrement mode is not valid for 68HC11."));
1232 mode
= M6812_POST_INC
;
1234 if (current_architecture
& cpu6811
)
1236 (_("Post-increment mode is not valid for 68HC11."));
1239 mode
= M6812_OP_IDX
;
1241 input_line_pointer
= p
;
1244 mode
|= M6812_OP_IDX
;
1249 input_line_pointer
= old_input_line
;
1252 if (mode
== M6812_OP_D_IDX_2
)
1254 as_bad (_("Invalid indexed indirect mode."));
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')
1267 input_line_pointer
= p
;
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. */
1278 check_range (num
, 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
;
1298 case M6811_OP_DIRECT
:
1299 return (num
>= 0 && num
<= 255) ? 1 : 0;
1301 case M6811_OP_BITMASK
:
1304 return (((num
& 0xFFFFFF00) == 0) || ((num
& 0xFFFFFF00) == 0xFFFFFF00))
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))
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;
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. */
1335 fixup8 (oper
, mode
, opmode
)
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
)
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;
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,
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);
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. */
1403 fixup16 (oper
, mode
, opmode
)
1406 int opmode ATTRIBUTE_UNUSED
;
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
)
1425 /* Now create a 16-bit fixup. */
1426 fixp
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 2,
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;
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. */
1446 fixup24 (oper
, mode
, opmode
)
1449 int opmode ATTRIBUTE_UNUSED
;
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
)
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);
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
)
1486 if (IS_OPCODE (code
, M6812_BSR
))
1488 else if (IS_OPCODE (code
, M6811_BSR
))
1490 else if (IS_OPCODE (code
, M6811_BRA
))
1491 return (current_architecture
& cpu6812
) ? M6812_JMP
: M6811_JMP
;
1493 as_fatal (_("Unexpected branch conversion with `%x'"), code
);
1495 /* Keep gcc happy. */
1499 /* Start a new insn that contains at least 'size' bytes. Record the
1500 line information of that insn in the dwarf2 debug sections. */
1502 m68hc11_new_insn (size
)
1507 f
= frag_more (size
);
1509 dwarf2_emit_insn (size
);
1514 /* Builds a jump instruction (bra, bcc, bsr). */
1516 build_jump_insn (opcode
, operands
, nb_operands
, jmp_mode
)
1517 struct m68hc11_opcode
*opcode
;
1528 /* The relative branch convertion is not supported for
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))))
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
);
1572 /* 68HC11: translate the bcc into b!cc +3; jmp <L>. */
1573 f
= m68hc11_new_insn (3);
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
);
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);
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
)
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
);
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
,
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
);
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. */
1671 build_dbranch_insn (opcode
, operands
, nb_operands
, jmp_mode
)
1672 struct m68hc11_opcode
*opcode
;
1681 /* The relative branch convertion is not supported for
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
)
1701 else if (opcode
->format
& M6812_OP_TBCC_MARKER
)
1704 if (!(opcode
->format
& M6812_OP_EQ_MARKER
))
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))))
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
);
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'"),
1738 number_to_chars_bigendian (f
, code
, 1);
1739 number_to_chars_bigendian (f
+ 1, n
& 0x0FF, 1);
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
);
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. */
1766 build_indexed_byte (op
, format
, move_insn
)
1768 int format ATTRIBUTE_UNUSED
;
1771 unsigned char byte
= 0;
1776 val
= op
->exp
.X_add_number
;
1778 if (mode
& M6812_AUTO_INC_DEC
)
1781 if (mode
& (M6812_POST_INC
| M6812_POST_DEC
))
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'."),
1791 if (mode
& (M6812_POST_INC
| M6812_PRE_INC
))
1792 byte
|= (val
- 1) & 0x07;
1794 byte
|= (8 - ((val
) & 7)) | 0x8;
1799 as_fatal (_("Expecting a register."));
1814 as_bad (_("Invalid register for post/pre increment."));
1819 number_to_chars_bigendian (f
, byte
, 1);
1823 if (mode
& (M6812_OP_IDX
| M6812_OP_D_IDX_2
))
1844 as_bad (_("Invalid register."));
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."),
1861 if (val
>= -16 && val
<= 15 && !(mode
& M6812_OP_D_IDX_2
))
1866 number_to_chars_bigendian (f
, byte
, 1);
1869 else if (val
>= -256 && val
<= 255 && !(mode
& M6812_OP_D_IDX_2
))
1876 number_to_chars_bigendian (f
, byte
, 1);
1877 number_to_chars_bigendian (f
+ 1, val
& 0x0FF, 1);
1883 if (mode
& M6812_OP_D_IDX_2
)
1889 number_to_chars_bigendian (f
, byte
, 1);
1890 number_to_chars_bigendian (f
+ 1, val
& 0x0FFFF, 2);
1894 if (mode
& M6812_OP_D_IDX_2
)
1896 byte
= (byte
<< 3) | 0xe3;
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;
1906 number_to_chars_bigendian (f
, byte
, 1);
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);
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
);
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."));
1932 as_bad (_("Indexed indirect mode is not allowed for movb/movw."));
1949 as_bad (_("Invalid accumulator register."));
1974 as_bad (_("Invalid indexed register."));
1978 number_to_chars_bigendian (f
, byte
, 1);
1982 as_fatal (_("Addressing mode not implemented yet."));
1986 /* Assemble the 68HC12 register mode byte. */
1988 build_reg_mode (op
, format
)
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
)
2013 number_to_chars_bigendian (f
, byte
, 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
2022 build_insn (opcode
, operands
, nb_operands
)
2023 struct m68hc11_opcode
*opcode
;
2025 int nb_operands ATTRIBUTE_UNUSED
;
2034 /* Put the page code instruction if there is one. */
2035 format
= opcode
->format
;
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
)
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
;
2054 page_code
= M6811_OPCODE_PAGE4
;
2056 number_to_chars_bigendian (f
, page_code
, 1);
2060 f
= m68hc11_new_insn (1);
2062 number_to_chars_bigendian (f
, opcode
->opcode
, 1);
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
))
2071 if (format
& M6812_OP_IDX
)
2073 build_indexed_byte (&operands
[0], format
, 1);
2075 format
&= ~M6812_OP_IDX
;
2077 if (format
& M6812_OP_IDX_P2
)
2079 build_indexed_byte (&operands
[1], format
, 1);
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
),
2092 else if (IS_CALL_SYMBOL (format
) && nb_operands
== 1)
2094 format
&= ~M6812_OP_PAGE
;
2095 fixup24 (&operands
[i
].exp
, format
& M6811_OP_IND16
,
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
),
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
);
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
);
2123 else if (format
& M6812_OP_REG
&& current_architecture
& cpu6812
)
2125 build_reg_mode (&operands
[i
], format
);
2128 if (format
& M6811_OP_BITMASK
)
2130 fixup8 (&operands
[i
].exp
, M6811_OP_BITMASK
, operands
[i
].mode
);
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
;
2159 struct m68hc11_opcode
*opcode
;
2160 struct m68hc11_opcode
*op_indirect
;
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
;
2175 if (opcode
->format
& M6811_OP_MASK
)
2177 if (opcode
->format
& M6811_OP_BITMASK
)
2179 if (opcode
->format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
2181 if (opcode
->format
& (M6812_OP_IND16_P2
| M6812_OP_IDX_P2
))
2183 if ((opcode
->format
& M6812_OP_PAGE
)
2184 && (!IS_CALL_SYMBOL (opcode
->format
) || nb_operands
== 2))
2187 for (i
= 0; expect
== nb_operands
&& i
< nb_operands
; i
++)
2189 int mode
= operands
[i
].mode
;
2191 if (mode
& M6811_OP_IMM16
)
2194 (M6811_OP_IMM8
| M6811_OP_IMM16
| M6811_OP_BITMASK
))
2198 if (mode
== M6811_OP_DIRECT
)
2200 if (format
& M6811_OP_DIRECT
)
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)
2214 if (mode
& M6811_OP_IND16
)
2216 if (i
== 0 && (format
& M6811_OP_IND16
) != 0)
2218 if (i
!= 0 && (format
& M6812_OP_PAGE
) != 0)
2220 if (i
!= 0 && (format
& M6812_OP_IND16_P2
) != 0)
2222 if (i
== 0 && (format
& M6811_OP_BITMASK
))
2225 if (mode
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
2227 if (format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
2230 if (mode
& M6812_OP_REG
)
2233 && (format
& M6812_OP_REG
)
2234 && (operands
[i
].reg2
== REG_NONE
))
2237 && (format
& M6812_OP_REG
)
2238 && (format
& M6812_OP_REG_2
)
2239 && (operands
[i
].reg2
!= REG_NONE
))
2242 && (format
& M6812_OP_IDX
)
2243 && (operands
[i
].reg2
!= REG_NONE
))
2246 && (format
& M6812_OP_IDX
)
2247 && (format
& (M6812_OP_IND16_P2
| M6812_OP_IDX_P2
)))
2250 && (format
& M6812_OP_IDX_P2
))
2254 if (mode
& M6812_OP_IDX
)
2256 if (format
& M6811_OP_IX
&& operands
[i
].reg1
== REG_X
)
2258 if (format
& M6811_OP_IY
&& operands
[i
].reg1
== REG_Y
)
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
))
2267 if (i
== 1 && format
& M6812_OP_IDX_P2
)
2270 if (mode
& format
& (M6812_OP_D_IDX
| M6812_OP_D_IDX_2
))
2275 if (mode
& M6812_AUTO_INC_DEC
)
2278 && format
& (M6812_OP_IDX
| M6812_OP_IDX_1
|
2281 if (i
== 1 && format
& M6812_OP_IDX_P2
)
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
;
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
;
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
;
2331 struct m68hc11_opcode
*opcode
;
2334 if (opc
->max_operands
== 0)
2340 for (i
= 0; i
< opc
->max_operands
;)
2344 result
= get_operand (&operands
[i
], i
, opc
->format
);
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
;
2359 if (i
>= opc
->min_operands
)
2361 opcode
= find (opc
, operands
, i
);
2362 if (opcode
&& !(opcode
->format
& M6812_OP_PAGE
))
2365 if (opcode
&& *input_line_pointer
!= ',')
2369 if (*input_line_pointer
== ',')
2370 input_line_pointer
++;
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. */
2389 struct m68hc11_opcode_def
*opc
;
2390 struct m68hc11_opcode
*opcode
;
2392 unsigned char *op_start
, *save
;
2393 unsigned char *op_end
;
2396 operand operands
[M6811_MAX_OPERANDS
];
2398 int branch_optimize
= 0;
2401 /* Drop leading whitespace. */
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
!= ' ';
2411 name
[nlen
] = TOLOWER (op_start
[nlen
]);
2418 as_bad (_("No instruction or missing opcode."));
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
2429 if (opc
== NULL
&& name
[0] == 'j' && name
[1] == 'b')
2431 opc
= (struct m68hc11_opcode_def
*) hash_find (m68hc11_hash
, &name
[1]);
2433 && (!(opc
->format
& M6811_OP_JUMP_REL
)
2434 || (opc
->format
& M6811_OP_BITMASK
)))
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')
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
++);
2462 opc
= (struct m68hc11_opcode_def
*) hash_find (m68hc11_hash
,
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
))
2474 for (i
= 0; i
< m68hc12_num_alias
; i
++)
2475 if (strcmp (m68hc12_alias
[i
].name
, name
) == 0)
2481 if (opc
== NULL
&& alias_id
< 0)
2483 as_bad (_("Opcode `%s' is not recognized."), name
);
2486 save
= input_line_pointer
;
2487 input_line_pointer
= op_end
;
2492 opcode
= find_opcode (opc
, operands
, &nb_operands
);
2497 if ((opcode
|| alias_id
>= 0) && !flag_mri
)
2499 char *p
= input_line_pointer
;
2501 while (*p
== ' ' || *p
== '\t' || *p
== '\n' || *p
== '\r')
2504 if (*p
!= '\n' && *p
)
2505 as_bad (_("Garbage at end of instruction: `%s'."), p
);
2508 input_line_pointer
= save
;
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);
2521 /* Opcode is known but does not have valid operands. Print out the
2522 syntax for this opcode. */
2525 if (flag_print_insn_syntax
)
2526 print_insn_format (name
);
2528 as_bad (_("Invalid operand for `%s'"), name
);
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
);
2546 build_insn (opcode
, operands
, nb_operands
);
2550 /* Pseudo op to control the ELF flags. */
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
;
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. */
2591 s_m68hc11_mark_symbol (mark
)
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
;
2609 bfdsym
= symbol_get_bfdsym (symbolP
);
2610 elfsym
= elf_symbol_from (bfd_asymbol_bfd (bfdsym
), bfdsym
);
2614 /* Mark the symbol far (using rtc for function return). */
2615 elfsym
->internal_elf_sym
.st_other
|= mark
;
2619 input_line_pointer
++;
2623 if (*input_line_pointer
== '\n')
2629 demand_empty_rest_of_line ();
2633 s_m68hc11_relax (ignore
)
2634 int ignore ATTRIBUTE_UNUSED
;
2640 if (ex
.X_op
!= O_symbol
|| ex
.X_add_number
!= 0)
2642 as_bad (_("bad .relax format"));
2643 ignore_rest_of_line ();
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. */
2660 md_pcrel_from (fixP
)
2663 if (fixP
->fx_r_type
== BFD_RELOC_M68HC11_RL_JUMP
)
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. */
2672 tc_gen_reloc (section
, fixp
)
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
);
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
);
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
;
2704 md_convert_frag (abfd
, sec
, fragP
)
2705 bfd
*abfd ATTRIBUTE_UNUSED
;
2706 asection
*sec ATTRIBUTE_UNUSED
;
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
;
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
);
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
;
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
);
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;
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;
2774 fragP
->fr_opcode
[0] |= value
& 0x1f;
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
);
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;
2797 fix_new (fragP
, fragP
->fr_fix
, 2,
2798 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_16
);
2803 case ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_BYTE
):
2805 fragP
->fr_opcode
[0] |= 0x10;
2807 fragP
->fr_opcode
[1] = disp
& 0x0FF;
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
);
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). */
2830 relaxable_symbol (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
)
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. */
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
);
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
;
2890 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
2891 fragP
->fr_offset
, 0, BFD_RELOC_16
);
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;
2902 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
2903 fragP
->fr_offset
, 0, BFD_RELOC_16
);
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
;
2918 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
2919 fragP
->fr_offset
, 0, BFD_RELOC_16
);
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
);
2936 as_fatal (_("Subtype %d is not recognized."), fragP
->fr_subtype
);
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
);
2956 case STATE_CONDITIONAL_BRANCH
:
2957 assert (current_architecture
& cpu6811
);
2959 fragP
->fr_subtype
= ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
,
2963 case STATE_INDEXED_OFFSET
:
2964 assert (current_architecture
& cpu6812
);
2966 fragP
->fr_subtype
= ENCODE_RELAX (STATE_INDEXED_OFFSET
,
2970 case STATE_XBCC_BRANCH
:
2971 assert (current_architecture
& cpu6812
);
2973 fragP
->fr_subtype
= ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_BYTE
);
2976 case STATE_CONDITIONAL_BRANCH_6812
:
2977 assert (current_architecture
& cpu6812
);
2979 fragP
->fr_subtype
= ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
,
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
)
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
:
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
3017 tc_m68hc11_fix_adjustable (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. */
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
:
3039 md_apply_fix3 (fixP
, valP
, seg
)
3042 segT seg ATTRIBUTE_UNUSED
;
3045 long value
= * valP
;
3048 if (fixP
->fx_addsy
== (symbolS
*) NULL
)
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
)
3071 bfd_putb32 ((bfd_vma
) value
, (unsigned char *) where
);
3075 case BFD_RELOC_M68HC11_24
:
3076 bfd_putb16 ((bfd_vma
) (value
& 0x0ffff), (unsigned char *) where
);
3077 ((bfd_byte
*) where
)[2] = ((value
>> 16) & 0x0ff);
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."));
3089 case BFD_RELOC_M68HC11_HI8
:
3093 case BFD_RELOC_M68HC11_LO8
:
3095 case BFD_RELOC_M68HC11_PAGE
:
3097 bfd_putb8 ((bfd_vma
) value
, (unsigned char *) where
);
3099 ((bfd_byte
*) where
)[0] = (bfd_byte
) value
;
3102 case BFD_RELOC_8_PCREL
:
3104 bfd_putb8 ((bfd_vma
) value
, (unsigned char *) where
);
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."),
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."),
3124 where
[0] = where
[0] | (value
& 0x07);
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
:
3135 as_fatal (_("Line %d: unknown relocation type: 0x%x."),
3136 fixP
->fx_line
, fixP
->fx_r_type
);
3140 /* Set the ELF specific flags. */
3142 m68hc11_elf_final_processing ()
3144 elf_elfheader (stdoutput
)->e_flags
&= ~EF_M68HC11_ABI
;
3145 elf_elfheader (stdoutput
)->e_flags
|= elf_flags
;