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 control the ELF flags. */
186 static void s_m68hc11_mode
PARAMS ((int));
188 /* Mark the symbols with STO_M68HC12_FAR to indicate the functions
189 are using 'rtc' for returning. It is necessary to use 'call'
190 to invoke them. This is also used by the debugger to correctly
191 find the stack frame. */
192 static void s_m68hc11_mark_symbol
PARAMS ((int));
194 /* Controls whether relative branches can be turned into long branches.
195 When the relative offset is too large, the insn are changed:
203 Setting the flag forbidds this. */
204 static short flag_fixed_branchs
= 0;
206 /* Force to use long jumps (absolute) instead of relative branches. */
207 static short flag_force_long_jumps
= 0;
209 /* Change the direct addressing mode into an absolute addressing mode
210 when the insn does not support direct addressing.
211 For example, "clr *ZD0" is normally not possible and is changed
213 static short flag_strict_direct_addressing
= 1;
215 /* When an opcode has invalid operand, print out the syntax of the opcode
217 static short flag_print_insn_syntax
= 0;
219 /* Dumps the list of instructions with syntax and then exit:
220 1 -> Only dumps the list (sorted by name)
221 2 -> Generate an example (or test) that can be compiled. */
222 static short flag_print_opcodes
= 0;
224 /* Opcode hash table. */
225 static struct hash_control
*m68hc11_hash
;
227 /* Current cpu (either cpu6811 or cpu6812). This is determined automagically
228 by 'get_default_target' by looking at default BFD vector. This is overriden
229 with the -m<cpu> option. */
230 static int current_architecture
= 0;
232 /* Default cpu determined by 'get_default_target'. */
233 static const char *default_cpu
;
235 /* Number of opcodes in the sorted table (filtered by current cpu). */
236 static int num_opcodes
;
238 /* The opcodes sorted by name and filtered by current cpu. */
239 static struct m68hc11_opcode
*m68hc11_sorted_opcodes
;
241 /* ELF flags to set in the output file header. */
242 static int elf_flags
= 0;
244 /* These are the machine dependent pseudo-ops. These are included so
245 the assembler can work on the output from the SUN C compiler, which
248 /* This table describes all the machine specific pseudo-ops the assembler
249 has to support. The fields are:
250 pseudo-op name without dot
251 function to call to execute this pseudo-op
252 Integer arg to pass to the function. */
253 const pseudo_typeS md_pseudo_table
[] = {
254 /* The following pseudo-ops are supported for MRI compatibility. */
257 {"fcc", stringer
, 1},
260 /* Dwarf2 support for Gcc. */
261 {"file", dwarf2_directive_file
, 0},
262 {"loc", dwarf2_directive_loc
, 0},
265 {"xrefb", s_ignore
, 0}, /* Same as xref */
267 /* .mode instruction (ala SH). */
268 {"mode", s_m68hc11_mode
, 0},
270 /* .far instruction. */
271 {"far", s_m68hc11_mark_symbol
, STO_M68HC12_FAR
},
273 /* .interrupt instruction. */
274 {"interrupt", s_m68hc11_mark_symbol
, STO_M68HC12_INTERRUPT
},
279 /* Options and initialization. */
281 const char *md_shortopts
= "Sm:";
283 struct option md_longopts
[] = {
284 #define OPTION_FORCE_LONG_BRANCH (OPTION_MD_BASE)
285 {"force-long-branchs", no_argument
, NULL
, OPTION_FORCE_LONG_BRANCH
},
287 #define OPTION_SHORT_BRANCHS (OPTION_MD_BASE + 1)
288 {"short-branchs", no_argument
, NULL
, OPTION_SHORT_BRANCHS
},
290 #define OPTION_STRICT_DIRECT_MODE (OPTION_MD_BASE + 2)
291 {"strict-direct-mode", no_argument
, NULL
, OPTION_STRICT_DIRECT_MODE
},
293 #define OPTION_PRINT_INSN_SYNTAX (OPTION_MD_BASE + 3)
294 {"print-insn-syntax", no_argument
, NULL
, OPTION_PRINT_INSN_SYNTAX
},
296 #define OPTION_PRINT_OPCODES (OPTION_MD_BASE + 4)
297 {"print-opcodes", no_argument
, NULL
, OPTION_PRINT_OPCODES
},
299 #define OPTION_GENERATE_EXAMPLE (OPTION_MD_BASE + 5)
300 {"generate-example", no_argument
, NULL
, OPTION_GENERATE_EXAMPLE
},
302 {NULL
, no_argument
, NULL
, 0}
304 size_t md_longopts_size
= sizeof (md_longopts
);
306 /* Get the target cpu for the assembler. This is based on the configure
307 options and on the -m68hc11/-m68hc12 option. If no option is specified,
308 we must get the default. */
310 m68hc11_arch_format ()
312 get_default_target ();
313 if (current_architecture
& cpu6811
)
314 return "elf32-m68hc11";
316 return "elf32-m68hc12";
319 enum bfd_architecture
322 get_default_target ();
323 if (current_architecture
& cpu6811
)
324 return bfd_arch_m68hc11
;
326 return bfd_arch_m68hc12
;
335 /* Listing header selected according to cpu. */
337 m68hc11_listing_header ()
339 if (current_architecture
& cpu6811
)
340 return "M68HC11 GAS ";
342 return "M68HC12 GAS ";
346 md_show_usage (stream
)
349 get_default_target ();
350 fprintf (stream
, _("\
351 Motorola 68HC11/68HC12 options:\n\
352 -m68hc11 | -m68hc12 specify the processor [default %s]\n\
353 --force-long-branchs always turn relative branchs into absolute ones\n\
354 -S,--short-branchs do not turn relative branchs into absolute ones\n\
355 when the offset is out of range\n\
356 --strict-direct-mode do not turn the direct mode into extended mode\n\
357 when the instruction does not support direct mode\n\
358 --print-insn-syntax print the syntax of instruction in case of error\n\
359 --print-opcodes print the list of instructions with syntax\n\
360 --generate-example generate an example of each instruction\n\
361 (used for testing)\n"), default_cpu
);
365 /* Try to identify the default target based on the BFD library. */
367 get_default_target ()
369 const bfd_target
*target
;
372 if (current_architecture
!= 0)
375 default_cpu
= "unknown";
376 target
= bfd_find_target (0, &abfd
);
377 if (target
&& target
->name
)
379 if (strcmp (target
->name
, "elf32-m68hc12") == 0)
381 current_architecture
= cpu6812
;
382 default_cpu
= "m68hc12";
384 else if (strcmp (target
->name
, "elf32-m68hc11") == 0)
386 current_architecture
= cpu6811
;
387 default_cpu
= "m68hc11";
391 as_bad (_("Default target `%s' is not supported."), target
->name
);
397 m68hc11_print_statistics (file
)
401 struct m68hc11_opcode_def
*opc
;
403 hash_print_statistics (file
, "opcode table", m68hc11_hash
);
405 opc
= m68hc11_opcode_defs
;
406 if (opc
== 0 || m68hc11_nb_opcode_defs
== 0)
409 /* Dump the opcode statistics table. */
410 fprintf (file
, _("Name # Modes Min ops Max ops Modes mask # Used\n"));
411 for (i
= 0; i
< m68hc11_nb_opcode_defs
; i
++, opc
++)
413 fprintf (file
, "%-7.7s %5d %7d %7d 0x%08lx %7d\n",
416 opc
->min_operands
, opc
->max_operands
, opc
->format
, opc
->used
);
421 md_parse_option (c
, arg
)
425 get_default_target ();
428 /* -S means keep external to 2 bit offset rather than 16 bit one. */
429 case OPTION_SHORT_BRANCHS
:
431 flag_fixed_branchs
= 1;
434 case OPTION_FORCE_LONG_BRANCH
:
435 flag_force_long_jumps
= 1;
438 case OPTION_PRINT_INSN_SYNTAX
:
439 flag_print_insn_syntax
= 1;
442 case OPTION_PRINT_OPCODES
:
443 flag_print_opcodes
= 1;
446 case OPTION_STRICT_DIRECT_MODE
:
447 flag_strict_direct_addressing
= 0;
450 case OPTION_GENERATE_EXAMPLE
:
451 flag_print_opcodes
= 2;
455 if (strcasecmp (arg
, "68hc11") == 0)
456 current_architecture
= cpu6811
;
457 else if (strcasecmp (arg
, "68hc12") == 0)
458 current_architecture
= cpu6812
;
460 as_bad (_("Option `%s' is not recognized."), arg
);
471 md_undefined_symbol (name
)
472 char *name ATTRIBUTE_UNUSED
;
477 /* Equal to MAX_PRECISION in atof-ieee.c. */
478 #define MAX_LITTLENUMS 6
480 /* Turn a string in input_line_pointer into a floating point constant
481 of type TYPE, and store the appropriate bytes in *LITP. The number
482 of LITTLENUMS emitted is stored in *SIZEP. An error message is
483 returned, or NULL on OK. */
485 md_atof (type
, litP
, sizeP
)
491 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
492 LITTLENUM_TYPE
*wordP
;
523 return _("Bad call to MD_ATOF()");
525 t
= atof_ieee (input_line_pointer
, type
, words
);
527 input_line_pointer
= t
;
529 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
530 for (wordP
= words
; prec
--;)
532 md_number_to_chars (litP
, (long) (*wordP
++), sizeof (LITTLENUM_TYPE
));
533 litP
+= sizeof (LITTLENUM_TYPE
);
539 md_section_align (seg
, addr
)
543 int align
= bfd_get_section_alignment (stdoutput
, seg
);
544 return ((addr
+ (1 << align
) - 1) & (-1 << align
));
548 cmp_opcode (op1
, op2
)
549 struct m68hc11_opcode
*op1
;
550 struct m68hc11_opcode
*op2
;
552 return strcmp (op1
->name
, op2
->name
);
555 #define IS_CALL_SYMBOL(MODE) \
556 (((MODE) & (M6812_OP_PAGE|M6811_OP_IND16)) \
557 == ((M6812_OP_PAGE|M6811_OP_IND16)))
559 /* Initialize the assembler. Create the opcode hash table
560 (sorted on the names) with the M6811 opcode table
561 (from opcode library). */
565 char *prev_name
= "";
566 struct m68hc11_opcode
*opcodes
;
567 struct m68hc11_opcode_def
*opc
= 0;
570 get_default_target ();
572 m68hc11_hash
= hash_new ();
574 /* Get a writable copy of the opcode table and sort it on the names. */
575 opcodes
= (struct m68hc11_opcode
*) xmalloc (m68hc11_num_opcodes
*
578 m68hc11_sorted_opcodes
= opcodes
;
580 for (i
= 0; i
< m68hc11_num_opcodes
; i
++)
582 if (m68hc11_opcodes
[i
].arch
& current_architecture
)
584 opcodes
[num_opcodes
] = m68hc11_opcodes
[i
];
585 if (opcodes
[num_opcodes
].name
[0] == 'b'
586 && opcodes
[num_opcodes
].format
& M6811_OP_JUMP_REL
587 && !(opcodes
[num_opcodes
].format
& M6811_OP_BITMASK
))
590 opcodes
[num_opcodes
] = m68hc11_opcodes
[i
];
593 for (j
= 0; alias_opcodes
[j
].name
!= 0; j
++)
594 if (strcmp (m68hc11_opcodes
[i
].name
, alias_opcodes
[j
].name
) == 0)
596 opcodes
[num_opcodes
] = m68hc11_opcodes
[i
];
597 opcodes
[num_opcodes
].name
= alias_opcodes
[j
].alias
;
603 qsort (opcodes
, num_opcodes
, sizeof (struct m68hc11_opcode
), cmp_opcode
);
605 opc
= (struct m68hc11_opcode_def
*)
606 xmalloc (num_opcodes
* sizeof (struct m68hc11_opcode_def
));
607 m68hc11_opcode_defs
= opc
--;
609 /* Insert unique names into hash table. The M6811 instruction set
610 has several identical opcode names that have different opcodes based
611 on the operands. This hash table then provides a quick index to
612 the first opcode with a particular name in the opcode table. */
613 for (i
= 0; i
< num_opcodes
; i
++, opcodes
++)
617 if (strcmp (prev_name
, opcodes
->name
))
619 prev_name
= (char *) opcodes
->name
;
623 opc
->min_operands
= 100;
624 opc
->max_operands
= 0;
626 opc
->opcode
= opcodes
;
628 hash_insert (m68hc11_hash
, opcodes
->name
, (char *) opc
);
631 opc
->format
|= opcodes
->format
;
633 /* See how many operands this opcode needs. */
635 if (opcodes
->format
& M6811_OP_MASK
)
637 if (opcodes
->format
& M6811_OP_BITMASK
)
639 if (opcodes
->format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
641 if (opcodes
->format
& (M6812_OP_IND16_P2
| M6812_OP_IDX_P2
))
643 /* Special case for call instruction. */
644 if ((opcodes
->format
& M6812_OP_PAGE
)
645 && !(opcodes
->format
& M6811_OP_IND16
))
648 if (expect
< opc
->min_operands
)
649 opc
->min_operands
= expect
;
650 if (IS_CALL_SYMBOL (opcodes
->format
))
652 if (expect
> opc
->max_operands
)
653 opc
->max_operands
= expect
;
656 m68hc11_nb_opcode_defs
= opc
- m68hc11_opcode_defs
;
658 if (flag_print_opcodes
)
660 print_opcode_list ();
666 m68hc11_init_after_args ()
672 /* Return a string that represents the operand format for the instruction.
673 When example is true, this generates an example of operand. This is used
674 to give an example and also to generate a test. */
676 print_opcode_format (opcode
, example
)
677 struct m68hc11_opcode
*opcode
;
680 static char buf
[128];
681 int format
= opcode
->format
;
686 if (format
& M6811_OP_IMM8
)
689 sprintf (p
, "#%d", rand () & 0x0FF);
691 strcpy (p
, _("#<imm8>"));
695 if (format
& M6811_OP_IMM16
)
698 sprintf (p
, "#%d", rand () & 0x0FFFF);
700 strcpy (p
, _("#<imm16>"));
704 if (format
& M6811_OP_IX
)
707 sprintf (p
, "%d,X", rand () & 0x0FF);
709 strcpy (p
, _("<imm8>,X"));
713 if (format
& M6811_OP_IY
)
716 sprintf (p
, "%d,X", rand () & 0x0FF);
718 strcpy (p
, _("<imm8>,X"));
722 if (format
& M6812_OP_IDX
)
725 sprintf (p
, "%d,X", rand () & 0x0FF);
731 if (format
& M6812_OP_PAGE
)
734 sprintf (p
, ", %d", rand () & 0x0FF);
736 strcpy (p
, ", <page>");
740 if (format
& M6811_OP_DIRECT
)
743 sprintf (p
, "*Z%d", rand () & 0x0FF);
745 strcpy (p
, _("*<abs8>"));
749 if (format
& M6811_OP_BITMASK
)
755 sprintf (p
, "#$%02x", rand () & 0x0FF);
757 strcpy (p
, _("#<mask>"));
760 if (format
& M6811_OP_JUMP_REL
)
764 if (format
& M6811_OP_IND16
)
767 sprintf (p
, _("symbol%d"), rand () & 0x0FF);
769 strcpy (p
, _("<abs>"));
774 if (format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
778 if (format
& M6811_OP_BITMASK
)
780 sprintf (p
, ".+%d", rand () & 0x7F);
784 sprintf (p
, "L%d", rand () & 0x0FF);
788 strcpy (p
, _("<label>"));
794 /* Prints the list of instructions with the possible operands. */
799 char *prev_name
= "";
800 struct m68hc11_opcode
*opcodes
;
801 int example
= flag_print_opcodes
== 2;
804 printf (_("# Example of `%s' instructions\n\t.sect .text\n_start:\n"),
807 opcodes
= m68hc11_sorted_opcodes
;
809 /* Walk the list sorted on names (by md_begin). We only report
810 one instruction per line, and we collect the different operand
812 for (i
= 0; i
< num_opcodes
; i
++, opcodes
++)
814 char *fmt
= print_opcode_format (opcodes
, example
);
818 printf ("L%d:\t", i
);
819 printf ("%s %s\n", opcodes
->name
, fmt
);
823 if (strcmp (prev_name
, opcodes
->name
))
828 printf ("%-5.5s ", opcodes
->name
);
829 prev_name
= (char *) opcodes
->name
;
832 printf (" [%s]", fmt
);
838 /* Print the instruction format. This operation is called when some
839 instruction is not correct. Instruction format is printed as an
842 print_insn_format (name
)
845 struct m68hc11_opcode_def
*opc
;
846 struct m68hc11_opcode
*opcode
;
849 opc
= (struct m68hc11_opcode_def
*) hash_find (m68hc11_hash
, name
);
852 as_bad (_("Instruction `%s' is not recognized."), name
);
855 opcode
= opc
->opcode
;
857 as_bad (_("Instruction formats for `%s':"), name
);
862 fmt
= print_opcode_format (opcode
, 0);
863 sprintf (buf
, "\t%-5.5s %s", opcode
->name
, fmt
);
868 while (strcmp (opcode
->name
, name
) == 0);
871 /* Analysis of 68HC11 and 68HC12 operands. */
873 /* reg_name_search() finds the register number given its name.
874 Returns the register number or REG_NONE on failure. */
876 reg_name_search (name
)
879 if (strcasecmp (name
, "x") == 0 || strcasecmp (name
, "ix") == 0)
881 if (strcasecmp (name
, "y") == 0 || strcasecmp (name
, "iy") == 0)
883 if (strcasecmp (name
, "a") == 0)
885 if (strcasecmp (name
, "b") == 0)
887 if (strcasecmp (name
, "d") == 0)
889 if (strcasecmp (name
, "sp") == 0)
891 if (strcasecmp (name
, "pc") == 0)
893 if (strcasecmp (name
, "ccr") == 0)
903 while (*p
== ' ' || *p
== '\t')
909 /* Check the string at input_line_pointer
910 to see if it is a valid register name. */
914 register_id reg_number
;
915 char c
, *p
= input_line_pointer
;
917 if (!is_name_beginner (*p
++))
920 while (is_part_of_name (*p
++))
927 /* Look to see if it's in the register table. */
928 reg_number
= reg_name_search (input_line_pointer
);
929 if (reg_number
!= REG_NONE
)
934 input_line_pointer
= p
;
943 /* Parse a string of operands and return an array of expressions.
945 Operand mode[0] mode[1] exp[0] exp[1]
946 #n M6811_OP_IMM16 - O_*
947 *<exp> M6811_OP_DIRECT - O_*
948 .{+-}<exp> M6811_OP_JUMP_REL - O_*
949 <exp> M6811_OP_IND16 - O_*
950 ,r N,r M6812_OP_IDX M6812_OP_REG O_constant O_register
951 n,-r M6812_PRE_DEC M6812_OP_REG O_constant O_register
952 n,+r M6812_PRE_INC " "
953 n,r- M6812_POST_DEC " "
954 n,r+ M6812_POST_INC " "
955 A,r B,r D,r M6811_OP_REG M6812_OP_REG O_register O_register
956 [D,r] M6811_OP_D_IDX M6812_OP_REG O_register O_register
957 [n,r] M6811_OP_D_IDX_2 M6812_OP_REG O_constant O_register */
959 get_operand (oper
, which
, opmode
)
964 char *p
= input_line_pointer
;
968 oper
->exp
.X_op
= O_absent
;
969 oper
->reg1
= REG_NONE
;
970 oper
->reg2
= REG_NONE
;
971 mode
= M6811_OP_NONE
;
975 if (*p
== 0 || *p
== '\n' || *p
== '\r')
977 input_line_pointer
= p
;
981 if (*p
== '*' && (opmode
& (M6811_OP_DIRECT
| M6811_OP_IND16
)))
983 mode
= M6811_OP_DIRECT
;
988 if (!(opmode
& (M6811_OP_IMM8
| M6811_OP_IMM16
| M6811_OP_BITMASK
)))
990 as_bad (_("Immediate operand is not allowed for operand %d."),
995 mode
= M6811_OP_IMM16
;
997 if (strncmp (p
, "%hi", 3) == 0)
1000 mode
|= M6811_OP_HIGH_ADDR
;
1002 else if (strncmp (p
, "%lo", 3) == 0)
1005 mode
|= M6811_OP_LOW_ADDR
;
1008 else if (*p
== '.' && (p
[1] == '+' || p
[1] == '-'))
1011 mode
= M6811_OP_JUMP_REL
;
1015 if (current_architecture
& cpu6811
)
1016 as_bad (_("Indirect indexed addressing is not valid for 68HC11."));
1019 mode
= M6812_OP_D_IDX
;
1020 p
= skip_whites (p
);
1022 else if (*p
== ',') /* Special handling of ,x and ,y. */
1025 input_line_pointer
= p
;
1027 reg
= register_name ();
1028 if (reg
!= REG_NONE
)
1031 oper
->exp
.X_op
= O_constant
;
1032 oper
->exp
.X_add_number
= 0;
1033 oper
->mode
= M6812_OP_IDX
;
1036 as_bad (_("Spurious `,' or bad indirect register addressing mode."));
1039 input_line_pointer
= p
;
1041 if (mode
== M6811_OP_NONE
|| mode
== M6812_OP_D_IDX
)
1042 reg
= register_name ();
1046 if (reg
!= REG_NONE
)
1048 p
= skip_whites (input_line_pointer
);
1049 if (*p
== ']' && mode
== M6812_OP_D_IDX
)
1052 (_("Missing second register or offset for indexed-indirect mode."));
1057 oper
->mode
= mode
| M6812_OP_REG
;
1060 if (mode
== M6812_OP_D_IDX
)
1062 as_bad (_("Missing second register for indexed-indirect mode."));
1069 input_line_pointer
= p
;
1070 reg
= register_name ();
1071 if (reg
!= REG_NONE
)
1073 p
= skip_whites (input_line_pointer
);
1074 if (mode
== M6812_OP_D_IDX
)
1078 as_bad (_("Missing `]' to close indexed-indirect mode."));
1082 oper
->mode
= M6812_OP_D_IDX
;
1084 input_line_pointer
= p
;
1092 /* In MRI mode, isolate the operand because we can't distinguish
1093 operands from comments. */
1098 p
= skip_whites (p
);
1099 while (*p
&& *p
!= ' ' && *p
!= '\t')
1108 /* Parse as an expression. */
1109 expression (&oper
->exp
);
1118 expression (&oper
->exp
);
1121 if (oper
->exp
.X_op
== O_illegal
)
1123 as_bad (_("Illegal operand."));
1126 else if (oper
->exp
.X_op
== O_absent
)
1128 as_bad (_("Missing operand."));
1132 p
= input_line_pointer
;
1134 if (mode
== M6811_OP_NONE
|| mode
== M6811_OP_DIRECT
1135 || mode
== M6812_OP_D_IDX
)
1137 p
= skip_whites (input_line_pointer
);
1141 int possible_mode
= M6811_OP_NONE
;
1142 char *old_input_line
;
1147 /* 68HC12 pre increment or decrement. */
1148 if (mode
== M6811_OP_NONE
)
1152 possible_mode
= M6812_PRE_DEC
;
1157 possible_mode
= M6812_PRE_INC
;
1160 p
= skip_whites (p
);
1162 input_line_pointer
= p
;
1163 reg
= register_name ();
1165 /* Backtrack if we have a valid constant expression and
1166 it does not correspond to the offset of the 68HC12 indexed
1167 addressing mode (as in N,x). */
1168 if (reg
== REG_NONE
&& mode
== M6811_OP_NONE
1169 && possible_mode
!= M6811_OP_NONE
)
1171 oper
->mode
= M6811_OP_IND16
| M6811_OP_JUMP_REL
;
1172 input_line_pointer
= skip_whites (old_input_line
);
1176 if (possible_mode
!= M6811_OP_NONE
)
1177 mode
= possible_mode
;
1179 if ((current_architecture
& cpu6811
)
1180 && possible_mode
!= M6811_OP_NONE
)
1181 as_bad (_("Pre-increment mode is not valid for 68HC11"));
1183 if (which
== 0 && opmode
& M6812_OP_IDX_P2
1184 && reg
!= REG_X
&& reg
!= REG_Y
1185 && reg
!= REG_PC
&& reg
!= REG_SP
)
1188 input_line_pointer
= p
;
1191 if (reg
== REG_NONE
&& mode
!= M6811_OP_DIRECT
1192 && !(mode
== M6811_OP_NONE
&& opmode
& M6811_OP_IND16
))
1194 as_bad (_("Wrong register in register indirect mode."));
1197 if (mode
== M6812_OP_D_IDX
)
1199 p
= skip_whites (input_line_pointer
);
1202 as_bad (_("Missing `]' to close register indirect operand."));
1205 input_line_pointer
= p
;
1207 oper
->mode
= M6812_OP_D_IDX_2
;
1210 if (reg
!= REG_NONE
)
1213 if (mode
== M6811_OP_NONE
)
1215 p
= input_line_pointer
;
1218 mode
= M6812_POST_DEC
;
1220 if (current_architecture
& cpu6811
)
1222 (_("Post-decrement mode is not valid for 68HC11."));
1226 mode
= M6812_POST_INC
;
1228 if (current_architecture
& cpu6811
)
1230 (_("Post-increment mode is not valid for 68HC11."));
1233 mode
= M6812_OP_IDX
;
1235 input_line_pointer
= p
;
1238 mode
|= M6812_OP_IDX
;
1243 input_line_pointer
= old_input_line
;
1246 if (mode
== M6812_OP_D_IDX_2
)
1248 as_bad (_("Invalid indexed indirect mode."));
1253 /* If the mode is not known until now, this is either a label
1254 or an indirect address. */
1255 if (mode
== M6811_OP_NONE
)
1256 mode
= M6811_OP_IND16
| M6811_OP_JUMP_REL
;
1258 p
= input_line_pointer
;
1259 while (*p
== ' ' || *p
== '\t')
1261 input_line_pointer
= p
;
1267 #define M6812_AUTO_INC_DEC (M6812_PRE_INC | M6812_PRE_DEC \
1268 | M6812_POST_INC | M6812_POST_DEC)
1270 /* Checks that the number 'num' fits for a given mode. */
1272 check_range (num
, mode
)
1276 /* Auto increment and decrement are ok for [-8..8] without 0. */
1277 if (mode
& M6812_AUTO_INC_DEC
)
1278 return (num
!= 0 && num
<= 8 && num
>= -8);
1280 /* The 68HC12 supports 5, 9 and 16-bit offsets. */
1281 if (mode
& (M6812_INDEXED_IND
| M6812_INDEXED
| M6812_OP_IDX
))
1282 mode
= M6811_OP_IND16
;
1284 if (mode
& M6812_OP_JUMP_REL16
)
1285 mode
= M6811_OP_IND16
;
1287 mode
&= ~M6811_OP_BRANCH
;
1292 case M6811_OP_DIRECT
:
1293 return (num
>= 0 && num
<= 255) ? 1 : 0;
1295 case M6811_OP_BITMASK
:
1298 return (((num
& 0xFFFFFF00) == 0) || ((num
& 0xFFFFFF00) == 0xFFFFFF00))
1301 case M6811_OP_JUMP_REL
:
1302 return (num
>= -128 && num
<= 127) ? 1 : 0;
1304 case M6811_OP_IND16
:
1305 case M6811_OP_IND16
| M6812_OP_PAGE
:
1306 case M6811_OP_IMM16
:
1307 return (((num
& 0xFFFF0000) == 0) || ((num
& 0xFFFF0000) == 0xFFFF0000))
1310 case M6812_OP_IBCC_MARKER
:
1311 case M6812_OP_TBCC_MARKER
:
1312 case M6812_OP_DBCC_MARKER
:
1313 return (num
>= -256 && num
<= 255) ? 1 : 0;
1315 case M6812_OP_TRAP_ID
:
1316 return ((num
>= 0x30 && num
<= 0x39)
1317 || (num
>= 0x40 && num
<= 0x0ff)) ? 1 : 0;
1324 /* Gas fixup generation. */
1326 /* Put a 1 byte expression described by 'oper'. If this expression contains
1327 unresolved symbols, generate an 8-bit fixup. */
1329 fixup8 (oper
, mode
, opmode
)
1338 if (oper
->X_op
== O_constant
)
1340 if (mode
& M6812_OP_TRAP_ID
1341 && !check_range (oper
->X_add_number
, M6812_OP_TRAP_ID
))
1343 static char trap_id_warn_once
= 0;
1345 as_bad (_("Trap id `%ld' is out of range."), oper
->X_add_number
);
1346 if (trap_id_warn_once
== 0)
1348 trap_id_warn_once
= 1;
1349 as_bad (_("Trap id must be within [0x30..0x39] or [0x40..0xff]."));
1353 if (!(mode
& M6812_OP_TRAP_ID
)
1354 && !check_range (oper
->X_add_number
, mode
))
1356 as_bad (_("Operand out of 8-bit range: `%ld'."), oper
->X_add_number
);
1358 number_to_chars_bigendian (f
, oper
->X_add_number
& 0x0FF, 1);
1360 else if (oper
->X_op
!= O_register
)
1362 if (mode
& M6812_OP_TRAP_ID
)
1363 as_bad (_("The trap id must be a constant."));
1365 if (mode
== M6811_OP_JUMP_REL
)
1369 fixp
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 1,
1370 oper
, true, BFD_RELOC_8_PCREL
);
1371 fixp
->fx_pcrel_adjust
= 1;
1375 /* Now create an 8-bit fixup. If there was some %hi or %lo
1376 modifier, generate the reloc accordingly. */
1377 fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 1,
1379 ((opmode
& M6811_OP_HIGH_ADDR
)
1380 ? BFD_RELOC_M68HC11_HI8
1381 : ((opmode
& M6811_OP_LOW_ADDR
)
1382 ? BFD_RELOC_M68HC11_LO8
1383 : ((mode
& M6812_OP_PAGE
)
1384 ? BFD_RELOC_M68HC11_PAGE
: BFD_RELOC_8
))));
1386 number_to_chars_bigendian (f
, 0, 1);
1390 as_fatal (_("Operand `%x' not recognized in fixup8."), oper
->X_op
);
1394 /* Put a 2 byte expression described by 'oper'. If this expression contains
1395 unresolved symbols, generate a 16-bit fixup. */
1397 fixup16 (oper
, mode
, opmode
)
1400 int opmode ATTRIBUTE_UNUSED
;
1406 if (oper
->X_op
== O_constant
)
1408 if (!check_range (oper
->X_add_number
, mode
))
1410 as_bad (_("Operand out of 16-bit range: `%ld'."),
1411 oper
->X_add_number
);
1413 number_to_chars_bigendian (f
, oper
->X_add_number
& 0x0FFFF, 2);
1415 else if (oper
->X_op
!= O_register
)
1419 /* Now create a 16-bit fixup. */
1420 fixp
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 2,
1422 (mode
& M6812_OP_JUMP_REL16
? true : false),
1423 (mode
& M6812_OP_JUMP_REL16
1424 ? BFD_RELOC_16_PCREL
1425 : (mode
& M6812_OP_PAGE
)
1426 ? BFD_RELOC_M68HC11_LO16
: BFD_RELOC_16
));
1427 number_to_chars_bigendian (f
, 0, 2);
1428 if (mode
& M6812_OP_JUMP_REL16
)
1429 fixp
->fx_pcrel_adjust
= 2;
1433 as_fatal (_("Operand `%x' not recognized in fixup16."), oper
->X_op
);
1437 /* Put a 3 byte expression described by 'oper'. If this expression contains
1438 unresolved symbols, generate a 24-bit fixup. */
1440 fixup24 (oper
, mode
, opmode
)
1443 int opmode ATTRIBUTE_UNUSED
;
1449 if (oper
->X_op
== O_constant
)
1451 if (!check_range (oper
->X_add_number
, mode
))
1453 as_bad (_("Operand out of 16-bit range: `%ld'."),
1454 oper
->X_add_number
);
1456 number_to_chars_bigendian (f
, oper
->X_add_number
& 0x0FFFFFF, 3);
1458 else if (oper
->X_op
!= O_register
)
1462 /* Now create a 24-bit fixup. */
1463 fixp
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 2,
1464 oper
, false, BFD_RELOC_M68HC11_24
);
1465 number_to_chars_bigendian (f
, 0, 3);
1469 as_fatal (_("Operand `%x' not recognized in fixup16."), oper
->X_op
);
1473 /* 68HC11 and 68HC12 code generation. */
1475 /* Translate the short branch/bsr instruction into a long branch. */
1476 static unsigned char
1477 convert_branch (code
)
1480 if (IS_OPCODE (code
, M6812_BSR
))
1482 else if (IS_OPCODE (code
, M6811_BSR
))
1484 else if (IS_OPCODE (code
, M6811_BRA
))
1485 return (current_architecture
& cpu6812
) ? M6812_JMP
: M6811_JMP
;
1487 as_fatal (_("Unexpected branch conversion with `%x'"), code
);
1489 /* Keep gcc happy. */
1493 /* Start a new insn that contains at least 'size' bytes. Record the
1494 line information of that insn in the dwarf2 debug sections. */
1496 m68hc11_new_insn (size
)
1501 f
= frag_more (size
);
1503 dwarf2_emit_insn (size
);
1508 /* Builds a jump instruction (bra, bcc, bsr). */
1510 build_jump_insn (opcode
, operands
, nb_operands
, jmp_mode
)
1511 struct m68hc11_opcode
*opcode
;
1520 /* The relative branch convertion is not supported for
1522 assert ((opcode
->format
& M6811_OP_BITMASK
) == 0);
1523 assert (nb_operands
== 1);
1524 assert (operands
[0].reg1
== REG_NONE
&& operands
[0].reg2
== REG_NONE
);
1526 code
= opcode
->opcode
;
1528 n
= operands
[0].exp
.X_add_number
;
1530 /* Turn into a long branch:
1531 - when force long branch option (and not for jbcc pseudos),
1532 - when jbcc and the constant is out of -128..127 range,
1533 - when branch optimization is allowed and branch out of range. */
1534 if ((jmp_mode
== 0 && flag_force_long_jumps
)
1535 || (operands
[0].exp
.X_op
== O_constant
1536 && (!check_range (n
, opcode
->format
) &&
1537 (jmp_mode
== 1 || flag_fixed_branchs
== 0))))
1539 if (code
== M6811_BSR
|| code
== M6811_BRA
|| code
== M6812_BSR
)
1541 code
= convert_branch (code
);
1543 f
= m68hc11_new_insn (1);
1544 number_to_chars_bigendian (f
, code
, 1);
1546 else if (current_architecture
& cpu6812
)
1548 /* 68HC12: translate the bcc into a lbcc. */
1549 f
= m68hc11_new_insn (2);
1550 number_to_chars_bigendian (f
, M6811_OPCODE_PAGE2
, 1);
1551 number_to_chars_bigendian (f
+ 1, code
, 1);
1552 fixup16 (&operands
[0].exp
, M6812_OP_JUMP_REL16
,
1553 M6812_OP_JUMP_REL16
);
1558 /* 68HC11: translate the bcc into b!cc +3; jmp <L>. */
1559 f
= m68hc11_new_insn (3);
1561 number_to_chars_bigendian (f
, code
, 1);
1562 number_to_chars_bigendian (f
+ 1, 3, 1);
1563 number_to_chars_bigendian (f
+ 2, M6811_JMP
, 1);
1565 fixup16 (&operands
[0].exp
, M6811_OP_IND16
, M6811_OP_IND16
);
1569 /* Branch with a constant that must fit in 8-bits. */
1570 if (operands
[0].exp
.X_op
== O_constant
)
1572 if (!check_range (n
, opcode
->format
))
1574 as_bad (_("Operand out of range for a relative branch: `%ld'"),
1577 else if (opcode
->format
& M6812_OP_JUMP_REL16
)
1579 f
= m68hc11_new_insn (4);
1580 number_to_chars_bigendian (f
, M6811_OPCODE_PAGE2
, 1);
1581 number_to_chars_bigendian (f
+ 1, code
, 1);
1582 number_to_chars_bigendian (f
+ 2, n
& 0x0ffff, 2);
1586 f
= m68hc11_new_insn (2);
1587 number_to_chars_bigendian (f
, code
, 1);
1588 number_to_chars_bigendian (f
+ 1, n
& 0x0FF, 1);
1591 else if (opcode
->format
& M6812_OP_JUMP_REL16
)
1593 f
= m68hc11_new_insn (2);
1594 number_to_chars_bigendian (f
, M6811_OPCODE_PAGE2
, 1);
1595 number_to_chars_bigendian (f
+ 1, code
, 1);
1596 fixup16 (&operands
[0].exp
, M6812_OP_JUMP_REL16
, M6812_OP_JUMP_REL16
);
1602 /* Branch offset must fit in 8-bits, don't do some relax. */
1603 if (jmp_mode
== 0 && flag_fixed_branchs
)
1605 opcode
= m68hc11_new_insn (1);
1606 number_to_chars_bigendian (opcode
, code
, 1);
1607 fixup8 (&operands
[0].exp
, M6811_OP_JUMP_REL
, M6811_OP_JUMP_REL
);
1610 /* bra/bsr made be changed into jmp/jsr. */
1611 else if (code
== M6811_BSR
|| code
== M6811_BRA
|| code
== M6812_BSR
)
1613 /* Allocate worst case storage. */
1614 opcode
= m68hc11_new_insn (3);
1615 number_to_chars_bigendian (opcode
, code
, 1);
1616 number_to_chars_bigendian (opcode
+ 1, 0, 1);
1617 frag_variant (rs_machine_dependent
, 1, 1,
1618 ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_UNDF
),
1619 operands
[0].exp
.X_add_symbol
, (offsetT
) n
,
1622 else if (current_architecture
& cpu6812
)
1624 opcode
= m68hc11_new_insn (2);
1625 number_to_chars_bigendian (opcode
, code
, 1);
1626 number_to_chars_bigendian (opcode
+ 1, 0, 1);
1627 frag_var (rs_machine_dependent
, 2, 2,
1628 ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
, STATE_UNDF
),
1629 operands
[0].exp
.X_add_symbol
, (offsetT
) n
, opcode
);
1633 opcode
= m68hc11_new_insn (2);
1634 number_to_chars_bigendian (opcode
, code
, 1);
1635 number_to_chars_bigendian (opcode
+ 1, 0, 1);
1636 frag_var (rs_machine_dependent
, 3, 3,
1637 ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
, STATE_UNDF
),
1638 operands
[0].exp
.X_add_symbol
, (offsetT
) n
, opcode
);
1643 /* Builds a dbne/dbeq/tbne/tbeq instruction. */
1645 build_dbranch_insn (opcode
, operands
, nb_operands
, jmp_mode
)
1646 struct m68hc11_opcode
*opcode
;
1655 /* The relative branch convertion is not supported for
1657 assert ((opcode
->format
& M6811_OP_BITMASK
) == 0);
1658 assert (nb_operands
== 2);
1659 assert (operands
[0].reg1
!= REG_NONE
);
1661 code
= opcode
->opcode
& 0x0FF;
1663 f
= m68hc11_new_insn (1);
1664 number_to_chars_bigendian (f
, code
, 1);
1666 n
= operands
[1].exp
.X_add_number
;
1667 code
= operands
[0].reg1
;
1669 if (operands
[0].reg1
== REG_NONE
|| operands
[0].reg1
== REG_CCR
1670 || operands
[0].reg1
== REG_PC
)
1671 as_bad (_("Invalid register for dbcc/tbcc instruction."));
1673 if (opcode
->format
& M6812_OP_IBCC_MARKER
)
1675 else if (opcode
->format
& M6812_OP_TBCC_MARKER
)
1678 if (!(opcode
->format
& M6812_OP_EQ_MARKER
))
1681 /* Turn into a long branch:
1682 - when force long branch option (and not for jbcc pseudos),
1683 - when jdbcc and the constant is out of -256..255 range,
1684 - when branch optimization is allowed and branch out of range. */
1685 if ((jmp_mode
== 0 && flag_force_long_jumps
)
1686 || (operands
[1].exp
.X_op
== O_constant
1687 && (!check_range (n
, M6812_OP_IBCC_MARKER
) &&
1688 (jmp_mode
== 1 || flag_fixed_branchs
== 0))))
1692 number_to_chars_bigendian (f
, code
, 1);
1693 number_to_chars_bigendian (f
+ 1, M6812_JMP
, 1);
1694 fixup16 (&operands
[0].exp
, M6811_OP_IND16
, M6811_OP_IND16
);
1698 /* Branch with a constant that must fit in 9-bits. */
1699 if (operands
[1].exp
.X_op
== O_constant
)
1701 if (!check_range (n
, M6812_OP_IBCC_MARKER
))
1703 as_bad (_("Operand out of range for a relative branch: `%ld'"),
1712 number_to_chars_bigendian (f
, code
, 1);
1713 number_to_chars_bigendian (f
+ 1, n
& 0x0FF, 1);
1718 /* Branch offset must fit in 8-bits, don't do some relax. */
1719 if (jmp_mode
== 0 && flag_fixed_branchs
)
1721 fixup8 (&operands
[0].exp
, M6811_OP_JUMP_REL
, M6811_OP_JUMP_REL
);
1727 number_to_chars_bigendian (f
, code
, 1);
1728 number_to_chars_bigendian (f
+ 1, 0, 1);
1729 frag_var (rs_machine_dependent
, 3, 3,
1730 ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_UNDF
),
1731 operands
[1].exp
.X_add_symbol
, (offsetT
) n
, f
);
1736 #define OP_EXTENDED (M6811_OP_PAGE2 | M6811_OP_PAGE3 | M6811_OP_PAGE4)
1738 /* Assemble the post index byte for 68HC12 extended addressing modes. */
1740 build_indexed_byte (op
, format
, move_insn
)
1742 int format ATTRIBUTE_UNUSED
;
1745 unsigned char byte
= 0;
1750 val
= op
->exp
.X_add_number
;
1752 if (mode
& M6812_AUTO_INC_DEC
)
1755 if (mode
& (M6812_POST_INC
| M6812_POST_DEC
))
1758 if (op
->exp
.X_op
== O_constant
)
1760 if (!check_range (val
, mode
))
1762 as_bad (_("Increment/decrement value is out of range: `%ld'."),
1765 if (mode
& (M6812_POST_INC
| M6812_PRE_INC
))
1766 byte
|= (val
- 1) & 0x07;
1768 byte
|= (8 - ((val
) & 7)) | 0x8;
1773 as_fatal (_("Expecting a register."));
1788 as_bad (_("Invalid register for post/pre increment."));
1793 number_to_chars_bigendian (f
, byte
, 1);
1797 if (mode
& (M6812_OP_IDX
| M6812_OP_D_IDX_2
))
1818 as_bad (_("Invalid register."));
1821 if (op
->exp
.X_op
== O_constant
)
1823 if (!check_range (val
, M6812_OP_IDX
))
1825 as_bad (_("Offset out of 16-bit range: %ld."), val
);
1828 if (move_insn
&& !(val
>= -16 && val
<= 15))
1830 as_bad (_("Offset out of 5-bit range for movw/movb insn: %ld."),
1835 if (val
>= -16 && val
<= 15 && !(mode
& M6812_OP_D_IDX_2
))
1840 number_to_chars_bigendian (f
, byte
, 1);
1843 else if (val
>= -256 && val
<= 255 && !(mode
& M6812_OP_D_IDX_2
))
1850 number_to_chars_bigendian (f
, byte
, 1);
1851 number_to_chars_bigendian (f
+ 1, val
& 0x0FF, 1);
1857 if (mode
& M6812_OP_D_IDX_2
)
1863 number_to_chars_bigendian (f
, byte
, 1);
1864 number_to_chars_bigendian (f
+ 1, val
& 0x0FFFF, 2);
1868 if (mode
& M6812_OP_D_IDX_2
)
1870 byte
= (byte
<< 3) | 0xe3;
1872 number_to_chars_bigendian (f
, byte
, 1);
1874 fixup16 (&op
->exp
, 0, 0);
1876 else if (op
->reg1
!= REG_PC
)
1878 byte
= (byte
<< 3) | 0xe2;
1880 number_to_chars_bigendian (f
, byte
, 1);
1883 fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 2,
1884 &op
->exp
, false, BFD_RELOC_16
);
1885 number_to_chars_bigendian (f
, 0, 2);
1890 number_to_chars_bigendian (f
, byte
, 1);
1891 frag_var (rs_machine_dependent
, 2, 2,
1892 ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_UNDF
),
1893 op
->exp
.X_add_symbol
,
1894 op
->exp
.X_add_number
, f
);
1899 if (mode
& (M6812_OP_REG
| M6812_OP_D_IDX
))
1901 if (mode
& M6812_OP_D_IDX
)
1903 if (op
->reg1
!= REG_D
)
1904 as_bad (_("Expecting register D for indexed indirect mode."));
1906 as_bad (_("Indexed indirect mode is not allowed for movb/movw."));
1923 as_bad (_("Invalid accumulator register."));
1948 as_bad (_("Invalid indexed register."));
1952 number_to_chars_bigendian (f
, byte
, 1);
1956 as_fatal (_("Addressing mode not implemented yet."));
1960 /* Assemble the 68HC12 register mode byte. */
1962 build_reg_mode (op
, format
)
1969 if (format
& M6812_OP_SEX_MARKER
1970 && op
->reg1
!= REG_A
&& op
->reg1
!= REG_B
&& op
->reg1
!= REG_CCR
)
1971 as_bad (_("Invalid source register for this instruction, use 'tfr'."));
1972 else if (op
->reg1
== REG_NONE
|| op
->reg1
== REG_PC
)
1973 as_bad (_("Invalid source register."));
1975 if (format
& M6812_OP_SEX_MARKER
1976 && op
->reg2
!= REG_D
1977 && op
->reg2
!= REG_X
&& op
->reg2
!= REG_Y
&& op
->reg2
!= REG_SP
)
1978 as_bad (_("Invalid destination register for this instruction, use 'tfr'."));
1979 else if (op
->reg2
== REG_NONE
|| op
->reg2
== REG_PC
)
1980 as_bad (_("Invalid destination register."));
1982 byte
= (op
->reg1
<< 4) | (op
->reg2
);
1983 if (format
& M6812_OP_EXG_MARKER
)
1987 number_to_chars_bigendian (f
, byte
, 1);
1991 /* build_insn takes a pointer to the opcode entry in the opcode table,
1992 the array of operand expressions and builds the correspding instruction.
1993 This operation only deals with non relative jumps insn (need special
1996 build_insn (opcode
, operands
, nb_operands
)
1997 struct m68hc11_opcode
*opcode
;
1999 int nb_operands ATTRIBUTE_UNUSED
;
2006 /* Put the page code instruction if there is one. */
2007 format
= opcode
->format
;
2008 if (format
& OP_EXTENDED
)
2012 f
= m68hc11_new_insn (2);
2013 if (format
& M6811_OP_PAGE2
)
2014 page_code
= M6811_OPCODE_PAGE2
;
2015 else if (format
& M6811_OP_PAGE3
)
2016 page_code
= M6811_OPCODE_PAGE3
;
2018 page_code
= M6811_OPCODE_PAGE4
;
2020 number_to_chars_bigendian (f
, page_code
, 1);
2024 f
= m68hc11_new_insn (1);
2026 number_to_chars_bigendian (f
, opcode
->opcode
, 1);
2030 /* The 68HC12 movb and movw instructions are special. We have to handle
2031 them in a special way. */
2032 if (format
& (M6812_OP_IND16_P2
| M6812_OP_IDX_P2
))
2035 if (format
& M6812_OP_IDX
)
2037 build_indexed_byte (&operands
[0], format
, 1);
2039 format
&= ~M6812_OP_IDX
;
2041 if (format
& M6812_OP_IDX_P2
)
2043 build_indexed_byte (&operands
[1], format
, 1);
2045 format
&= ~M6812_OP_IDX_P2
;
2049 if (format
& (M6811_OP_DIRECT
| M6811_OP_IMM8
))
2051 fixup8 (&operands
[i
].exp
,
2052 format
& (M6811_OP_DIRECT
| M6811_OP_IMM8
| M6812_OP_TRAP_ID
),
2056 else if (IS_CALL_SYMBOL (format
) && nb_operands
== 1)
2058 format
&= ~M6812_OP_PAGE
;
2059 fixup24 (&operands
[i
].exp
, format
& M6811_OP_IND16
,
2063 else if (format
& (M6811_OP_IMM16
| M6811_OP_IND16
))
2065 fixup16 (&operands
[i
].exp
,
2066 format
& (M6811_OP_IMM16
| M6811_OP_IND16
| M6812_OP_PAGE
),
2070 else if (format
& (M6811_OP_IX
| M6811_OP_IY
))
2072 if ((format
& M6811_OP_IX
) && (operands
[0].reg1
!= REG_X
))
2073 as_bad (_("Invalid indexed register, expecting register X."));
2074 if ((format
& M6811_OP_IY
) && (operands
[0].reg1
!= REG_Y
))
2075 as_bad (_("Invalid indexed register, expecting register Y."));
2077 fixup8 (&operands
[0].exp
, M6811_OP_IX
, operands
[0].mode
);
2081 (M6812_OP_IDX
| M6812_OP_IDX_2
| M6812_OP_IDX_1
2082 | M6812_OP_D_IDX
| M6812_OP_D_IDX_2
))
2084 build_indexed_byte (&operands
[i
], format
, move_insn
);
2087 else if (format
& M6812_OP_REG
&& current_architecture
& cpu6812
)
2089 build_reg_mode (&operands
[i
], format
);
2092 if (format
& M6811_OP_BITMASK
)
2094 fixup8 (&operands
[i
].exp
, M6811_OP_BITMASK
, operands
[i
].mode
);
2097 if (format
& M6811_OP_JUMP_REL
)
2099 fixup8 (&operands
[i
].exp
, M6811_OP_JUMP_REL
, operands
[i
].mode
);
2101 else if (format
& M6812_OP_IND16_P2
)
2103 fixup16 (&operands
[1].exp
, M6811_OP_IND16
, operands
[1].mode
);
2105 if (format
& M6812_OP_PAGE
)
2107 fixup8 (&operands
[i
].exp
, M6812_OP_PAGE
, operands
[i
].mode
);
2111 /* Opcode identification and operand analysis. */
2113 /* find() gets a pointer to an entry in the opcode table. It must look at all
2114 opcodes with the same name and use the operands to choose the correct
2115 opcode. Returns the opcode pointer if there was a match and 0 if none. */
2116 static struct m68hc11_opcode
*
2117 find (opc
, operands
, nb_operands
)
2118 struct m68hc11_opcode_def
*opc
;
2123 struct m68hc11_opcode
*opcode
;
2124 struct m68hc11_opcode
*op_indirect
;
2127 opcode
= opc
->opcode
;
2129 /* Now search the opcode table table for one with operands
2130 that matches what we've got. We're only done if the operands matched so
2131 far AND there are no more to check. */
2132 for (pos
= match
= 0; match
== 0 && pos
< opc
->nb_modes
; pos
++, opcode
++)
2134 int poss_indirect
= 0;
2135 long format
= opcode
->format
;
2139 if (opcode
->format
& M6811_OP_MASK
)
2141 if (opcode
->format
& M6811_OP_BITMASK
)
2143 if (opcode
->format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
2145 if (opcode
->format
& (M6812_OP_IND16_P2
| M6812_OP_IDX_P2
))
2147 if ((opcode
->format
& M6812_OP_PAGE
)
2148 && (!IS_CALL_SYMBOL (opcode
->format
) || nb_operands
== 2))
2151 for (i
= 0; expect
== nb_operands
&& i
< nb_operands
; i
++)
2153 int mode
= operands
[i
].mode
;
2155 if (mode
& M6811_OP_IMM16
)
2158 (M6811_OP_IMM8
| M6811_OP_IMM16
| M6811_OP_BITMASK
))
2162 if (mode
== M6811_OP_DIRECT
)
2164 if (format
& M6811_OP_DIRECT
)
2167 /* If the operand is a page 0 operand, remember a
2168 possible <abs-16> addressing mode. We mark
2169 this and continue to check other operands. */
2170 if (format
& M6811_OP_IND16
2171 && flag_strict_direct_addressing
&& op_indirect
== 0)
2178 if (mode
& M6811_OP_IND16
)
2180 if (i
== 0 && (format
& M6811_OP_IND16
) != 0)
2182 if (i
!= 0 && (format
& M6812_OP_PAGE
) != 0)
2184 if (i
!= 0 && (format
& M6812_OP_IND16_P2
) != 0)
2186 if (i
== 0 && (format
& M6811_OP_BITMASK
))
2189 if (mode
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
2191 if (format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
2194 if (mode
& M6812_OP_REG
)
2197 && (format
& M6812_OP_REG
)
2198 && (operands
[i
].reg2
== REG_NONE
))
2201 && (format
& M6812_OP_REG
)
2202 && (format
& M6812_OP_REG_2
)
2203 && (operands
[i
].reg2
!= REG_NONE
))
2206 && (format
& M6812_OP_IDX
)
2207 && (operands
[i
].reg2
!= REG_NONE
))
2210 && (format
& M6812_OP_IDX
)
2211 && (format
& (M6812_OP_IND16_P2
| M6812_OP_IDX_P2
)))
2214 && (format
& M6812_OP_IDX_P2
))
2218 if (mode
& M6812_OP_IDX
)
2220 if (format
& M6811_OP_IX
&& operands
[i
].reg1
== REG_X
)
2222 if (format
& M6811_OP_IY
&& operands
[i
].reg1
== REG_Y
)
2225 && format
& (M6812_OP_IDX
| M6812_OP_IDX_1
| M6812_OP_IDX_2
)
2226 && (operands
[i
].reg1
== REG_X
2227 || operands
[i
].reg1
== REG_Y
2228 || operands
[i
].reg1
== REG_SP
2229 || operands
[i
].reg1
== REG_PC
))
2231 if (i
== 1 && format
& M6812_OP_IDX_P2
)
2234 if (mode
& format
& (M6812_OP_D_IDX
| M6812_OP_D_IDX_2
))
2239 if (mode
& M6812_AUTO_INC_DEC
)
2242 && format
& (M6812_OP_IDX
| M6812_OP_IDX_1
|
2245 if (i
== 1 && format
& M6812_OP_IDX_P2
)
2250 match
= i
== nb_operands
;
2252 /* Operands are ok but an operand uses page 0 addressing mode
2253 while the insn supports abs-16 mode. Keep a reference to this
2254 insns in case there is no insn supporting page 0 addressing. */
2255 if (match
&& poss_indirect
)
2257 op_indirect
= opcode
;
2264 /* Page 0 addressing is used but not supported by any insn.
2265 If absolute addresses are supported, we use that insn. */
2266 if (match
== 0 && op_indirect
)
2268 opcode
= op_indirect
;
2280 /* Find the real opcode and its associated operands. We use a progressive
2281 approach here. On entry, 'opc' points to the first opcode in the
2282 table that matches the opcode name in the source line. We try to
2283 isolate an operand, find a possible match in the opcode table.
2284 We isolate another operand if no match were found. The table 'operands'
2285 is filled while operands are recognized.
2287 Returns the opcode pointer that matches the opcode name in the
2288 source line and the associated operands. */
2289 static struct m68hc11_opcode
*
2290 find_opcode (opc
, operands
, nb_operands
)
2291 struct m68hc11_opcode_def
*opc
;
2295 struct m68hc11_opcode
*opcode
;
2298 if (opc
->max_operands
== 0)
2304 for (i
= 0; i
< opc
->max_operands
;)
2308 result
= get_operand (&operands
[i
], i
, opc
->format
);
2312 /* Special case where the bitmask of the bclr/brclr
2313 instructions is not introduced by #.
2314 Example: bclr 3,x $80. */
2315 if (i
== 1 && (opc
->format
& M6811_OP_BITMASK
)
2316 && (operands
[i
].mode
& M6811_OP_IND16
))
2318 operands
[i
].mode
= M6811_OP_IMM16
;
2323 if (i
>= opc
->min_operands
)
2325 opcode
= find (opc
, operands
, i
);
2326 if (opcode
&& !(opcode
->format
& M6812_OP_PAGE
))
2329 if (opcode
&& *input_line_pointer
!= ',')
2333 if (*input_line_pointer
== ',')
2334 input_line_pointer
++;
2340 #define M6812_XBCC_MARKER (M6812_OP_TBCC_MARKER \
2341 | M6812_OP_DBCC_MARKER \
2342 | M6812_OP_IBCC_MARKER)
2344 /* Gas line assembler entry point. */
2346 /* This is the main entry point for the machine-dependent assembler. str
2347 points to a machine-dependent instruction. This function is supposed to
2348 emit the frags/bytes it assembles to. */
2353 struct m68hc11_opcode_def
*opc
;
2354 struct m68hc11_opcode
*opcode
;
2356 unsigned char *op_start
, *save
;
2357 unsigned char *op_end
;
2360 operand operands
[M6811_MAX_OPERANDS
];
2362 int branch_optimize
= 0;
2365 /* Drop leading whitespace. */
2369 /* Find the opcode end and get the opcode in 'name'. The opcode is forced
2370 lower case (the opcode table only has lower case op-codes). */
2371 for (op_start
= op_end
= (unsigned char *) (str
);
2372 *op_end
&& nlen
< 20 && !is_end_of_line
[*op_end
] && *op_end
!= ' ';
2375 name
[nlen
] = TOLOWER (op_start
[nlen
]);
2382 as_bad (_("No instruction or missing opcode."));
2386 /* Find the opcode definition given its name. */
2387 opc
= (struct m68hc11_opcode_def
*) hash_find (m68hc11_hash
, name
);
2389 /* If it's not recognized, look for 'jbsr' and 'jbxx'. These are
2390 pseudo insns for relative branch. For these branchs, we always
2391 optimize them (turned into absolute branchs) even if --short-branchs
2393 if (opc
== NULL
&& name
[0] == 'j' && name
[1] == 'b')
2395 opc
= (struct m68hc11_opcode_def
*) hash_find (m68hc11_hash
, &name
[1]);
2397 && (!(opc
->format
& M6811_OP_JUMP_REL
)
2398 || (opc
->format
& M6811_OP_BITMASK
)))
2401 branch_optimize
= 1;
2404 /* The following test should probably be removed. This is not conform
2405 to Motorola assembler specs. */
2406 if (opc
== NULL
&& flag_mri
)
2408 if (*op_end
== ' ' || *op_end
== '\t')
2410 while (*op_end
== ' ' || *op_end
== '\t')
2415 (is_end_of_line
[op_end
[1]]
2416 || op_end
[1] == ' ' || op_end
[1] == '\t'
2417 || !ISALNUM (op_end
[1])))
2418 && (*op_end
== 'a' || *op_end
== 'b'
2419 || *op_end
== 'A' || *op_end
== 'B'
2420 || *op_end
== 'd' || *op_end
== 'D'
2421 || *op_end
== 'x' || *op_end
== 'X'
2422 || *op_end
== 'y' || *op_end
== 'Y'))
2424 name
[nlen
++] = TOLOWER (*op_end
++);
2426 opc
= (struct m68hc11_opcode_def
*) hash_find (m68hc11_hash
,
2432 /* Identify a possible instruction alias. There are some on the
2433 68HC12 to emulate a few 68HC11 instructions. */
2434 if (opc
== NULL
&& (current_architecture
& cpu6812
))
2438 for (i
= 0; i
< m68hc12_num_alias
; i
++)
2439 if (strcmp (m68hc12_alias
[i
].name
, name
) == 0)
2445 if (opc
== NULL
&& alias_id
< 0)
2447 as_bad (_("Opcode `%s' is not recognized."), name
);
2450 save
= input_line_pointer
;
2451 input_line_pointer
= op_end
;
2456 opcode
= find_opcode (opc
, operands
, &nb_operands
);
2461 if ((opcode
|| alias_id
>= 0) && !flag_mri
)
2463 char *p
= input_line_pointer
;
2465 while (*p
== ' ' || *p
== '\t' || *p
== '\n' || *p
== '\r')
2468 if (*p
!= '\n' && *p
)
2469 as_bad (_("Garbage at end of instruction: `%s'."), p
);
2472 input_line_pointer
= save
;
2476 char *f
= m68hc11_new_insn (m68hc12_alias
[alias_id
].size
);
2478 number_to_chars_bigendian (f
, m68hc12_alias
[alias_id
].code1
, 1);
2479 if (m68hc12_alias
[alias_id
].size
> 1)
2480 number_to_chars_bigendian (f
+ 1, m68hc12_alias
[alias_id
].code2
, 1);
2485 /* Opcode is known but does not have valid operands. Print out the
2486 syntax for this opcode. */
2489 if (flag_print_insn_syntax
)
2490 print_insn_format (name
);
2492 as_bad (_("Invalid operand for `%s'"), name
);
2496 /* Treat dbeq/ibeq/tbeq instructions in a special way. The branch is
2497 relative and must be in the range -256..255 (9-bits). */
2498 if ((opcode
->format
& M6812_XBCC_MARKER
)
2499 && (opcode
->format
& M6811_OP_JUMP_REL
))
2500 build_dbranch_insn (opcode
, operands
, nb_operands
, branch_optimize
);
2502 /* Relative jumps instructions are taken care of separately. We have to make
2503 sure that the relative branch is within the range -128..127. If it's out
2504 of range, the instructions are changed into absolute instructions.
2505 This is not supported for the brset and brclr instructions. */
2506 else if ((opcode
->format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
2507 && !(opcode
->format
& M6811_OP_BITMASK
))
2508 build_jump_insn (opcode
, operands
, nb_operands
, branch_optimize
);
2510 build_insn (opcode
, operands
, nb_operands
);
2514 /* Pseudo op to control the ELF flags. */
2517 int x ATTRIBUTE_UNUSED
;
2519 char *name
= input_line_pointer
, ch
;
2521 while (!is_end_of_line
[(unsigned char) *input_line_pointer
])
2522 input_line_pointer
++;
2523 ch
= *input_line_pointer
;
2524 *input_line_pointer
= '\0';
2526 if (strcmp (name
, "mshort") == 0)
2528 elf_flags
&= ~E_M68HC11_I32
;
2530 else if (strcmp (name
, "mlong") == 0)
2532 elf_flags
|= E_M68HC11_I32
;
2534 else if (strcmp (name
, "mshort-double") == 0)
2536 elf_flags
&= ~E_M68HC11_F64
;
2538 else if (strcmp (name
, "mlong-double") == 0)
2540 elf_flags
|= E_M68HC11_F64
;
2544 as_warn (_("Invalid mode: %s\n"), name
);
2546 *input_line_pointer
= ch
;
2547 demand_empty_rest_of_line ();
2550 /* Mark the symbols with STO_M68HC12_FAR to indicate the functions
2551 are using 'rtc' for returning. It is necessary to use 'call'
2552 to invoke them. This is also used by the debugger to correctly
2553 find the stack frame. */
2555 s_m68hc11_mark_symbol (mark
)
2562 elf_symbol_type
*elfsym
;
2566 name
= input_line_pointer
;
2567 c
= get_symbol_end ();
2568 symbolP
= symbol_find_or_make (name
);
2569 *input_line_pointer
= c
;
2573 bfdsym
= symbol_get_bfdsym (symbolP
);
2574 elfsym
= elf_symbol_from (bfd_asymbol_bfd (bfdsym
), bfdsym
);
2578 /* Mark the symbol far (using rtc for function return). */
2579 elfsym
->internal_elf_sym
.st_other
|= mark
;
2583 input_line_pointer
++;
2587 if (*input_line_pointer
== '\n')
2593 demand_empty_rest_of_line ();
2596 /* Relocation, relaxation and frag conversions. */
2598 md_pcrel_from_section (fixp
, sec
)
2603 if (fixp
->fx_addsy
!= (symbolS
*) NULL
2604 && (!S_IS_DEFINED (fixp
->fx_addsy
)
2605 || (S_GET_SEGMENT (fixp
->fx_addsy
) != sec
)))
2608 adjust
= fixp
->fx_pcrel_adjust
;
2609 return fixp
->fx_frag
->fr_address
+ fixp
->fx_where
+ adjust
;
2612 /* If while processing a fixup, a reloc really needs to be created
2613 then it is done here. */
2615 tc_gen_reloc (section
, fixp
)
2621 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
2622 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
2623 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
2624 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
2625 if (fixp
->fx_r_type
== 0)
2626 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_16
);
2628 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
2629 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
2631 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2632 _("Relocation %d is not supported by object file format."),
2633 (int) fixp
->fx_r_type
);
2637 if (!fixp
->fx_pcrel
)
2638 reloc
->addend
= fixp
->fx_addnumber
;
2640 reloc
->addend
= (section
->vma
2641 + (fixp
->fx_pcrel_adjust
== 64
2642 ? -1 : fixp
->fx_pcrel_adjust
)
2643 + fixp
->fx_addnumber
2644 + md_pcrel_from_section (fixp
, section
));
2649 md_convert_frag (abfd
, sec
, fragP
)
2650 bfd
*abfd ATTRIBUTE_UNUSED
;
2651 asection
*sec ATTRIBUTE_UNUSED
;
2657 char *buffer_address
= fragP
->fr_literal
;
2659 /* Address in object code of the displacement. */
2660 register int object_address
= fragP
->fr_fix
+ fragP
->fr_address
;
2662 buffer_address
+= fragP
->fr_fix
;
2664 /* The displacement of the address, from current location. */
2665 value
= S_GET_VALUE (fragP
->fr_symbol
);
2666 disp
= (value
+ fragP
->fr_offset
) - object_address
;
2668 switch (fragP
->fr_subtype
)
2670 case ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_BYTE
):
2671 fragP
->fr_opcode
[1] = disp
;
2674 case ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_WORD
):
2675 /* This relax is only for bsr and bra. */
2676 assert (IS_OPCODE (fragP
->fr_opcode
[0], M6811_BSR
)
2677 || IS_OPCODE (fragP
->fr_opcode
[0], M6811_BRA
)
2678 || IS_OPCODE (fragP
->fr_opcode
[0], M6812_BSR
));
2680 fragP
->fr_opcode
[0] = convert_branch (fragP
->fr_opcode
[0]);
2682 fix_new (fragP
, fragP
->fr_fix
- 1, 2,
2683 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_16
);
2687 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
, STATE_BYTE
):
2688 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
, STATE_BYTE
):
2689 fragP
->fr_opcode
[1] = disp
;
2692 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
, STATE_WORD
):
2693 /* Invert branch. */
2694 fragP
->fr_opcode
[0] ^= 1;
2695 fragP
->fr_opcode
[1] = 3; /* Branch offset. */
2696 buffer_address
[0] = M6811_JMP
;
2697 fix_new (fragP
, fragP
->fr_fix
+ 1, 2,
2698 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_16
);
2702 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
, STATE_WORD
):
2703 /* Translate branch into a long branch. */
2704 fragP
->fr_opcode
[1] = fragP
->fr_opcode
[0];
2705 fragP
->fr_opcode
[0] = M6811_OPCODE_PAGE2
;
2707 fixp
= fix_new (fragP
, fragP
->fr_fix
, 2,
2708 fragP
->fr_symbol
, fragP
->fr_offset
, 1,
2709 BFD_RELOC_16_PCREL
);
2710 fixp
->fx_pcrel_adjust
= 2;
2714 case ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS5
):
2715 fragP
->fr_opcode
[0] = fragP
->fr_opcode
[0] << 6;
2716 if ((fragP
->fr_opcode
[0] & 0x0ff) == 0x0c0)
2717 fragP
->fr_opcode
[0] |= disp
& 0x1f;
2719 fragP
->fr_opcode
[0] |= value
& 0x1f;
2722 case ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS9
):
2723 fragP
->fr_opcode
[0] = (fragP
->fr_opcode
[0] << 3);
2724 fragP
->fr_opcode
[0] |= 0xE0;
2725 fix_new (fragP
, fragP
->fr_fix
, 1,
2726 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_8
);
2730 case ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS16
):
2731 fragP
->fr_opcode
[0] = (fragP
->fr_opcode
[0] << 3);
2732 fragP
->fr_opcode
[0] |= 0xe2;
2733 if ((fragP
->fr_opcode
[0] & 0x0ff) == 0x0fa)
2735 fixp
= fix_new (fragP
, fragP
->fr_fix
, 2,
2736 fragP
->fr_symbol
, fragP
->fr_offset
,
2737 1, BFD_RELOC_16_PCREL
);
2738 fixp
->fx_pcrel_adjust
= 2;
2742 fix_new (fragP
, fragP
->fr_fix
, 2,
2743 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_16
);
2748 case ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_BYTE
):
2750 fragP
->fr_opcode
[0] |= 0x10;
2752 fragP
->fr_opcode
[1] = disp
& 0x0FF;
2755 case ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_WORD
):
2756 /* Invert branch. */
2757 fragP
->fr_opcode
[0] ^= 0x20;
2758 fragP
->fr_opcode
[1] = 3; /* Branch offset. */
2759 buffer_address
[0] = M6812_JMP
;
2760 fix_new (fragP
, fragP
->fr_fix
+ 1, 2,
2761 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_16
);
2770 /* On an ELF system, we can't relax a weak symbol. The weak symbol
2771 can be overridden at final link time by a non weak symbol. We can
2772 relax externally visible symbol because there is no shared library
2773 and such symbol can't be overridden (unless they are weak). */
2775 relaxable_symbol (symbol
)
2778 return ! S_IS_WEAK (symbol
);
2781 /* Force truly undefined symbols to their maximum size, and generally set up
2782 the frag list to be relaxed. */
2784 md_estimate_size_before_relax (fragP
, segment
)
2788 if (RELAX_LENGTH (fragP
->fr_subtype
) == STATE_UNDF
)
2790 if (S_GET_SEGMENT (fragP
->fr_symbol
) != segment
2791 || !relaxable_symbol (fragP
->fr_symbol
))
2793 /* Non-relaxable cases. */
2795 char *buffer_address
;
2797 old_fr_fix
= fragP
->fr_fix
;
2798 buffer_address
= fragP
->fr_fix
+ fragP
->fr_literal
;
2800 switch (RELAX_STATE (fragP
->fr_subtype
))
2802 case STATE_PC_RELATIVE
:
2804 /* This relax is only for bsr and bra. */
2805 assert (IS_OPCODE (fragP
->fr_opcode
[0], M6811_BSR
)
2806 || IS_OPCODE (fragP
->fr_opcode
[0], M6811_BRA
)
2807 || IS_OPCODE (fragP
->fr_opcode
[0], M6812_BSR
));
2809 if (flag_fixed_branchs
)
2810 as_bad_where (fragP
->fr_file
, fragP
->fr_line
,
2811 _("bra or bsr with undefined symbol."));
2813 /* The symbol is undefined or in a separate section.
2814 Turn bra into a jmp and bsr into a jsr. The insn
2815 becomes 3 bytes long (instead of 2). A fixup is
2816 necessary for the unresolved symbol address. */
2817 fragP
->fr_opcode
[0] = convert_branch (fragP
->fr_opcode
[0]);
2819 fix_new (fragP
, fragP
->fr_fix
- 1, 2, fragP
->fr_symbol
,
2820 fragP
->fr_offset
, 0, BFD_RELOC_16
);
2824 case STATE_CONDITIONAL_BRANCH
:
2825 assert (current_architecture
& cpu6811
);
2827 fragP
->fr_opcode
[0] ^= 1; /* Reverse sense of branch. */
2828 fragP
->fr_opcode
[1] = 3; /* Skip next jmp insn (3 bytes). */
2830 /* Don't use fr_opcode[2] because this may be
2831 in a different frag. */
2832 buffer_address
[0] = M6811_JMP
;
2835 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
2836 fragP
->fr_offset
, 0, BFD_RELOC_16
);
2840 case STATE_INDEXED_OFFSET
:
2841 assert (current_architecture
& cpu6812
);
2843 /* Switch the indexed operation to 16-bit mode. */
2844 fragP
->fr_opcode
[0] = fragP
->fr_opcode
[0] << 3;
2845 fragP
->fr_opcode
[0] |= 0xe2;
2847 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
2848 fragP
->fr_offset
, 0, BFD_RELOC_16
);
2852 case STATE_XBCC_BRANCH
:
2853 assert (current_architecture
& cpu6812
);
2855 fragP
->fr_opcode
[0] ^= 0x20; /* Reverse sense of branch. */
2856 fragP
->fr_opcode
[1] = 3; /* Skip next jmp insn (3 bytes). */
2858 /* Don't use fr_opcode[2] because this may be
2859 in a different frag. */
2860 buffer_address
[0] = M6812_JMP
;
2863 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
2864 fragP
->fr_offset
, 0, BFD_RELOC_16
);
2868 case STATE_CONDITIONAL_BRANCH_6812
:
2869 assert (current_architecture
& cpu6812
);
2871 /* Translate into a lbcc branch. */
2872 fragP
->fr_opcode
[1] = fragP
->fr_opcode
[0];
2873 fragP
->fr_opcode
[0] = M6811_OPCODE_PAGE2
;
2875 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
2876 fragP
->fr_offset
, 0, BFD_RELOC_16_PCREL
);
2881 as_fatal (_("Subtype %d is not recognized."), fragP
->fr_subtype
);
2885 /* Return the growth in the fixed part of the frag. */
2886 return fragP
->fr_fix
- old_fr_fix
;
2889 /* Relaxable cases. */
2890 switch (RELAX_STATE (fragP
->fr_subtype
))
2892 case STATE_PC_RELATIVE
:
2893 /* This relax is only for bsr and bra. */
2894 assert (IS_OPCODE (fragP
->fr_opcode
[0], M6811_BSR
)
2895 || IS_OPCODE (fragP
->fr_opcode
[0], M6811_BRA
)
2896 || IS_OPCODE (fragP
->fr_opcode
[0], M6812_BSR
));
2898 fragP
->fr_subtype
= ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_BYTE
);
2901 case STATE_CONDITIONAL_BRANCH
:
2902 assert (current_architecture
& cpu6811
);
2904 fragP
->fr_subtype
= ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
,
2908 case STATE_INDEXED_OFFSET
:
2909 assert (current_architecture
& cpu6812
);
2911 fragP
->fr_subtype
= ENCODE_RELAX (STATE_INDEXED_OFFSET
,
2915 case STATE_XBCC_BRANCH
:
2916 assert (current_architecture
& cpu6812
);
2918 fragP
->fr_subtype
= ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_BYTE
);
2921 case STATE_CONDITIONAL_BRANCH_6812
:
2922 assert (current_architecture
& cpu6812
);
2924 fragP
->fr_subtype
= ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
,
2930 if (fragP
->fr_subtype
>= sizeof (md_relax_table
) / sizeof (md_relax_table
[0]))
2931 as_fatal (_("Subtype %d is not recognized."), fragP
->fr_subtype
);
2933 /* Return the size of the variable part of the frag. */
2934 return md_relax_table
[fragP
->fr_subtype
].rlx_length
;
2938 md_apply_fix3 (fixP
, valP
, seg
)
2941 segT seg ATTRIBUTE_UNUSED
;
2944 long value
= * valP
;
2947 if (fixP
->fx_addsy
== (symbolS
*) NULL
)
2950 else if (fixP
->fx_pcrel
)
2955 value
= fixP
->fx_offset
;
2957 if (fixP
->fx_subsy
!= (symbolS
*) NULL
)
2959 if (S_GET_SEGMENT (fixP
->fx_subsy
) == absolute_section
)
2960 value
-= S_GET_VALUE (fixP
->fx_subsy
);
2962 /* We don't actually support subtracting a symbol. */
2963 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2964 _("Expression too complex."));
2968 op_type
= fixP
->fx_r_type
;
2970 /* Patch the instruction with the resolved operand. Elf relocation
2971 info will also be generated to take care of linker/loader fixups.
2972 The 68HC11 addresses only 64Kb, we are only concerned by 8 and 16-bit
2973 relocs. BFD_RELOC_8 is basically used for .page0 access (the linker
2974 will warn for overflows). BFD_RELOC_8_PCREL should not be generated
2975 because it's either resolved or turned out into non-relative insns (see
2976 relax table, bcc, bra, bsr transformations)
2978 The BFD_RELOC_32 is necessary for the support of --gstabs. */
2979 where
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
2981 switch (fixP
->fx_r_type
)
2984 bfd_putb32 ((bfd_vma
) value
, (unsigned char *) where
);
2988 case BFD_RELOC_M68HC11_24
:
2989 bfd_putb16 ((bfd_vma
) (value
& 0x0ffff), (unsigned char *) where
);
2990 ((bfd_byte
*) where
)[2] = ((value
>> 16) & 0x0ff);
2994 case BFD_RELOC_16_PCREL
:
2995 case BFD_RELOC_M68HC11_LO16
:
2996 bfd_putb16 ((bfd_vma
) value
, (unsigned char *) where
);
2997 if (value
< -65537 || value
> 65535)
2998 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2999 _("Value out of 16-bit range."));
3002 case BFD_RELOC_M68HC11_HI8
:
3006 case BFD_RELOC_M68HC11_LO8
:
3008 case BFD_RELOC_M68HC11_PAGE
:
3010 bfd_putb8 ((bfd_vma
) value
, (unsigned char *) where
);
3012 ((bfd_byte
*) where
)[0] = (bfd_byte
) value
;
3015 case BFD_RELOC_8_PCREL
:
3017 bfd_putb8 ((bfd_vma
) value
, (unsigned char *) where
);
3019 ((bfd_byte
*) where
)[0] = (bfd_byte
) value
;
3021 if (value
< -128 || value
> 127)
3022 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3023 _("Value %ld too large for 8-bit PC-relative branch."),
3027 case BFD_RELOC_M68HC11_3B
:
3028 if (value
<= 0 || value
> 8)
3029 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3030 _("Auto increment/decrement offset '%ld' is out of range."),
3037 where
[0] = where
[0] | (value
& 0x07);
3041 as_fatal (_("Line %d: unknown relocation type: 0x%x."),
3042 fixP
->fx_line
, fixP
->fx_r_type
);
3046 /* Set the ELF specific flags. */
3048 m68hc11_elf_final_processing ()
3050 elf_elfheader (stdoutput
)->e_flags
&= ~EF_M68HC11_ABI
;
3051 elf_elfheader (stdoutput
)->e_flags
|= elf_flags
;