1 /* tc-m68hc11.c -- Assembler code for the Motorola 68HC11 & 68HC12.
2 Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005
3 Free Software Foundation, Inc.
4 Written by Stephane Carrez (stcarrez@nerim.fr)
6 This file is part of GAS, the GNU Assembler.
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 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_INDEXED_PCREL (4)
41 #define STATE_XBCC_BRANCH (5)
42 #define STATE_CONDITIONAL_BRANCH_6812 (6)
44 #define STATE_BYTE (0)
45 #define STATE_BITS5 (0)
46 #define STATE_WORD (1)
47 #define STATE_BITS9 (1)
48 #define STATE_LONG (2)
49 #define STATE_BITS16 (2)
50 #define STATE_UNDF (3) /* Symbol undefined in pass1 */
52 /* This macro has no side-effects. */
53 #define ENCODE_RELAX(what,length) (((what) << 2) + (length))
54 #define RELAX_STATE(s) ((s) >> 2)
55 #define RELAX_LENGTH(s) ((s) & 3)
57 #define IS_OPCODE(C1,C2) (((C1) & 0x0FF) == ((C2) & 0x0FF))
59 /* This table describes how you change sizes for the various types of variable
60 size expressions. This version only supports two kinds. */
63 How far Forward this mode will reach.
64 How far Backward this mode will reach.
65 How many bytes this mode will add to the size of the frag.
66 Which mode to go to if the offset won't fit in this one. */
68 relax_typeS md_relax_table
[] = {
69 {1, 1, 0, 0}, /* First entries aren't used. */
70 {1, 1, 0, 0}, /* For no good reason except. */
71 {1, 1, 0, 0}, /* that the VAX doesn't either. */
75 These insns are translated into b!cc +3 jmp L. */
76 {(127), (-128), 0, ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
, STATE_WORD
)},
81 /* Relax for bsr <L> and bra <L>.
82 These insns are translated into jsr and jmp. */
83 {(127), (-128), 0, ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_WORD
)},
88 /* Relax for indexed offset: 5-bits, 9-bits, 16-bits. */
89 {(15), (-16), 0, ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS9
)},
90 {(255), (-256), 1, ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS16
)},
94 /* Relax for PC relative offset: 5-bits, 9-bits, 16-bits.
95 For the 9-bit case, there will be a -1 correction to take into
96 account the new byte that's why the range is -255..256. */
97 {(15), (-16), 0, ENCODE_RELAX (STATE_INDEXED_PCREL
, STATE_BITS9
)},
98 {(256), (-255), 1, ENCODE_RELAX (STATE_INDEXED_PCREL
, STATE_BITS16
)},
102 /* Relax for dbeq/ibeq/tbeq r,<L>:
103 These insns are translated into db!cc +3 jmp L. */
104 {(255), (-256), 0, ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_WORD
)},
109 /* Relax for bcc <L> on 68HC12.
110 These insns are translated into lbcc <L>. */
111 {(127), (-128), 0, ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
, STATE_WORD
)},
118 /* 68HC11 and 68HC12 registers. They are numbered according to the 68HC12. */
119 typedef enum register_id
{
131 typedef struct operand
{
138 struct m68hc11_opcode_def
{
144 struct m68hc11_opcode
*opcode
;
147 static struct m68hc11_opcode_def
*m68hc11_opcode_defs
= 0;
148 static int m68hc11_nb_opcode_defs
= 0;
150 typedef struct alias
{
155 static alias alias_opcodes
[] = {
162 /* Local functions. */
163 static register_id
reg_name_search (char *);
164 static register_id
register_name (void);
165 static int cmp_opcode (struct m68hc11_opcode
*, struct m68hc11_opcode
*);
166 static char *print_opcode_format (struct m68hc11_opcode
*, int);
167 static char *skip_whites (char *);
168 static int check_range (long, int);
169 static void print_opcode_list (void);
170 static void get_default_target (void);
171 static void print_insn_format (char *);
172 static int get_operand (operand
*, int, long);
173 static void fixup8 (expressionS
*, int, int);
174 static void fixup16 (expressionS
*, int, int);
175 static void fixup24 (expressionS
*, int, int);
176 static unsigned char convert_branch (unsigned char);
177 static char *m68hc11_new_insn (int);
178 static void build_dbranch_insn (struct m68hc11_opcode
*,
179 operand
*, int, int);
180 static int build_indexed_byte (operand
*, int, int);
181 static int build_reg_mode (operand
*, int);
183 static struct m68hc11_opcode
*find (struct m68hc11_opcode_def
*,
185 static struct m68hc11_opcode
*find_opcode (struct m68hc11_opcode_def
*,
187 static void build_jump_insn (struct m68hc11_opcode
*, operand
*, int, int);
188 static void build_insn (struct m68hc11_opcode
*, operand
*, int);
189 static int relaxable_symbol (symbolS
*);
191 /* Pseudo op to indicate a relax group. */
192 static void s_m68hc11_relax (int);
194 /* Pseudo op to control the ELF flags. */
195 static void s_m68hc11_mode (int);
197 /* Mark the symbols with STO_M68HC12_FAR to indicate the functions
198 are using 'rtc' for returning. It is necessary to use 'call'
199 to invoke them. This is also used by the debugger to correctly
200 find the stack frame. */
201 static void s_m68hc11_mark_symbol (int);
203 /* Controls whether relative branches can be turned into long branches.
204 When the relative offset is too large, the insn are changed:
212 Setting the flag forbidds this. */
213 static short flag_fixed_branchs
= 0;
215 /* Force to use long jumps (absolute) instead of relative branches. */
216 static short flag_force_long_jumps
= 0;
218 /* Change the direct addressing mode into an absolute addressing mode
219 when the insn does not support direct addressing.
220 For example, "clr *ZD0" is normally not possible and is changed
222 static short flag_strict_direct_addressing
= 1;
224 /* When an opcode has invalid operand, print out the syntax of the opcode
226 static short flag_print_insn_syntax
= 0;
228 /* Dumps the list of instructions with syntax and then exit:
229 1 -> Only dumps the list (sorted by name)
230 2 -> Generate an example (or test) that can be compiled. */
231 static short flag_print_opcodes
= 0;
233 /* Opcode hash table. */
234 static struct hash_control
*m68hc11_hash
;
236 /* Current cpu (either cpu6811 or cpu6812). This is determined automagically
237 by 'get_default_target' by looking at default BFD vector. This is overridden
238 with the -m<cpu> option. */
239 static int current_architecture
= 0;
241 /* Default cpu determined by 'get_default_target'. */
242 static const char *default_cpu
;
244 /* Number of opcodes in the sorted table (filtered by current cpu). */
245 static int num_opcodes
;
247 /* The opcodes sorted by name and filtered by current cpu. */
248 static struct m68hc11_opcode
*m68hc11_sorted_opcodes
;
250 /* ELF flags to set in the output file header. */
251 static int elf_flags
= E_M68HC11_F64
;
253 /* These are the machine dependent pseudo-ops. These are included so
254 the assembler can work on the output from the SUN C compiler, which
257 /* This table describes all the machine specific pseudo-ops the assembler
258 has to support. The fields are:
259 pseudo-op name without dot
260 function to call to execute this pseudo-op
261 Integer arg to pass to the function. */
262 const pseudo_typeS md_pseudo_table
[] = {
263 /* The following pseudo-ops are supported for MRI compatibility. */
266 {"fcc", stringer
, 1},
270 {"xrefb", s_ignore
, 0}, /* Same as xref */
272 /* Gcc driven relaxation. */
273 {"relax", s_m68hc11_relax
, 0},
275 /* .mode instruction (ala SH). */
276 {"mode", s_m68hc11_mode
, 0},
278 /* .far instruction. */
279 {"far", s_m68hc11_mark_symbol
, STO_M68HC12_FAR
},
281 /* .interrupt instruction. */
282 {"interrupt", s_m68hc11_mark_symbol
, STO_M68HC12_INTERRUPT
},
287 /* Options and initialization. */
289 const char *md_shortopts
= "Sm:";
291 struct option md_longopts
[] = {
292 #define OPTION_FORCE_LONG_BRANCH (OPTION_MD_BASE)
293 {"force-long-branchs", no_argument
, NULL
, OPTION_FORCE_LONG_BRANCH
},
295 #define OPTION_SHORT_BRANCHS (OPTION_MD_BASE + 1)
296 {"short-branchs", no_argument
, NULL
, OPTION_SHORT_BRANCHS
},
298 #define OPTION_STRICT_DIRECT_MODE (OPTION_MD_BASE + 2)
299 {"strict-direct-mode", no_argument
, NULL
, OPTION_STRICT_DIRECT_MODE
},
301 #define OPTION_PRINT_INSN_SYNTAX (OPTION_MD_BASE + 3)
302 {"print-insn-syntax", no_argument
, NULL
, OPTION_PRINT_INSN_SYNTAX
},
304 #define OPTION_PRINT_OPCODES (OPTION_MD_BASE + 4)
305 {"print-opcodes", no_argument
, NULL
, OPTION_PRINT_OPCODES
},
307 #define OPTION_GENERATE_EXAMPLE (OPTION_MD_BASE + 5)
308 {"generate-example", no_argument
, NULL
, OPTION_GENERATE_EXAMPLE
},
310 #define OPTION_MSHORT (OPTION_MD_BASE + 6)
311 {"mshort", no_argument
, NULL
, OPTION_MSHORT
},
313 #define OPTION_MLONG (OPTION_MD_BASE + 7)
314 {"mlong", no_argument
, NULL
, OPTION_MLONG
},
316 #define OPTION_MSHORT_DOUBLE (OPTION_MD_BASE + 8)
317 {"mshort-double", no_argument
, NULL
, OPTION_MSHORT_DOUBLE
},
319 #define OPTION_MLONG_DOUBLE (OPTION_MD_BASE + 9)
320 {"mlong-double", no_argument
, NULL
, OPTION_MLONG_DOUBLE
},
322 {NULL
, no_argument
, NULL
, 0}
324 size_t md_longopts_size
= sizeof (md_longopts
);
326 /* Get the target cpu for the assembler. This is based on the configure
327 options and on the -m68hc11/-m68hc12 option. If no option is specified,
328 we must get the default. */
330 m68hc11_arch_format (void)
332 get_default_target ();
333 if (current_architecture
& cpu6811
)
334 return "elf32-m68hc11";
336 return "elf32-m68hc12";
339 enum bfd_architecture
342 get_default_target ();
343 if (current_architecture
& cpu6811
)
344 return bfd_arch_m68hc11
;
346 return bfd_arch_m68hc12
;
355 /* Listing header selected according to cpu. */
357 m68hc11_listing_header (void)
359 if (current_architecture
& cpu6811
)
360 return "M68HC11 GAS ";
362 return "M68HC12 GAS ";
366 md_show_usage (FILE *stream
)
368 get_default_target ();
369 fprintf (stream
, _("\
370 Motorola 68HC11/68HC12/68HCS12 options:\n\
371 -m68hc11 | -m68hc12 |\n\
372 -m68hcs12 specify the processor [default %s]\n\
373 -mshort use 16-bit int ABI (default)\n\
374 -mlong use 32-bit int ABI\n\
375 -mshort-double use 32-bit double ABI\n\
376 -mlong-double use 64-bit double ABI (default)\n\
377 --force-long-branchs always turn relative branchs into absolute ones\n\
378 -S,--short-branchs do not turn relative branchs into absolute ones\n\
379 when the offset is out of range\n\
380 --strict-direct-mode do not turn the direct mode into extended mode\n\
381 when the instruction does not support direct mode\n\
382 --print-insn-syntax print the syntax of instruction in case of error\n\
383 --print-opcodes print the list of instructions with syntax\n\
384 --generate-example generate an example of each instruction\n\
385 (used for testing)\n"), default_cpu
);
389 /* Try to identify the default target based on the BFD library. */
391 get_default_target (void)
393 const bfd_target
*target
;
396 if (current_architecture
!= 0)
399 default_cpu
= "unknown";
400 target
= bfd_find_target (0, &abfd
);
401 if (target
&& target
->name
)
403 if (strcmp (target
->name
, "elf32-m68hc12") == 0)
405 current_architecture
= cpu6812
;
406 default_cpu
= "m68hc12";
408 else if (strcmp (target
->name
, "elf32-m68hc11") == 0)
410 current_architecture
= cpu6811
;
411 default_cpu
= "m68hc11";
415 as_bad (_("Default target `%s' is not supported."), target
->name
);
421 m68hc11_print_statistics (FILE *file
)
424 struct m68hc11_opcode_def
*opc
;
426 hash_print_statistics (file
, "opcode table", m68hc11_hash
);
428 opc
= m68hc11_opcode_defs
;
429 if (opc
== 0 || m68hc11_nb_opcode_defs
== 0)
432 /* Dump the opcode statistics table. */
433 fprintf (file
, _("Name # Modes Min ops Max ops Modes mask # Used\n"));
434 for (i
= 0; i
< m68hc11_nb_opcode_defs
; i
++, opc
++)
436 fprintf (file
, "%-7.7s %5d %7d %7d 0x%08lx %7d\n",
439 opc
->min_operands
, opc
->max_operands
, opc
->format
, opc
->used
);
444 md_parse_option (int c
, char *arg
)
446 get_default_target ();
449 /* -S means keep external to 2 bit offset rather than 16 bit one. */
450 case OPTION_SHORT_BRANCHS
:
452 flag_fixed_branchs
= 1;
455 case OPTION_FORCE_LONG_BRANCH
:
456 flag_force_long_jumps
= 1;
459 case OPTION_PRINT_INSN_SYNTAX
:
460 flag_print_insn_syntax
= 1;
463 case OPTION_PRINT_OPCODES
:
464 flag_print_opcodes
= 1;
467 case OPTION_STRICT_DIRECT_MODE
:
468 flag_strict_direct_addressing
= 0;
471 case OPTION_GENERATE_EXAMPLE
:
472 flag_print_opcodes
= 2;
476 elf_flags
&= ~E_M68HC11_I32
;
480 elf_flags
|= E_M68HC11_I32
;
483 case OPTION_MSHORT_DOUBLE
:
484 elf_flags
&= ~E_M68HC11_F64
;
487 case OPTION_MLONG_DOUBLE
:
488 elf_flags
|= E_M68HC11_F64
;
492 if (strcasecmp (arg
, "68hc11") == 0)
493 current_architecture
= cpu6811
;
494 else if (strcasecmp (arg
, "68hc12") == 0)
495 current_architecture
= cpu6812
;
496 else if (strcasecmp (arg
, "68hcs12") == 0)
497 current_architecture
= cpu6812
| cpu6812s
;
499 as_bad (_("Option `%s' is not recognized."), arg
);
510 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
515 /* Equal to MAX_PRECISION in atof-ieee.c. */
516 #define MAX_LITTLENUMS 6
518 /* Turn a string in input_line_pointer into a floating point constant
519 of type TYPE, and store the appropriate bytes in *LITP. The number
520 of LITTLENUMS emitted is stored in *SIZEP. An error message is
521 returned, or NULL on OK. */
523 md_atof (int type
, char *litP
, int *sizeP
)
526 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
527 LITTLENUM_TYPE
*wordP
;
558 return _("Bad call to MD_ATOF()");
560 t
= atof_ieee (input_line_pointer
, type
, words
);
562 input_line_pointer
= t
;
564 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
565 for (wordP
= words
; prec
--;)
567 md_number_to_chars (litP
, (long) (*wordP
++), sizeof (LITTLENUM_TYPE
));
568 litP
+= sizeof (LITTLENUM_TYPE
);
574 md_section_align (asection
*seg
, valueT addr
)
576 int align
= bfd_get_section_alignment (stdoutput
, seg
);
577 return ((addr
+ (1 << align
) - 1) & (-1 << align
));
581 cmp_opcode (struct m68hc11_opcode
*op1
, struct m68hc11_opcode
*op2
)
583 return strcmp (op1
->name
, op2
->name
);
586 #define IS_CALL_SYMBOL(MODE) \
587 (((MODE) & (M6812_OP_PAGE|M6811_OP_IND16)) \
588 == ((M6812_OP_PAGE|M6811_OP_IND16)))
590 /* Initialize the assembler. Create the opcode hash table
591 (sorted on the names) with the M6811 opcode table
592 (from opcode library). */
596 char *prev_name
= "";
597 struct m68hc11_opcode
*opcodes
;
598 struct m68hc11_opcode_def
*opc
= 0;
601 get_default_target ();
603 m68hc11_hash
= hash_new ();
605 /* Get a writable copy of the opcode table and sort it on the names. */
606 opcodes
= (struct m68hc11_opcode
*) xmalloc (m68hc11_num_opcodes
*
609 m68hc11_sorted_opcodes
= opcodes
;
611 for (i
= 0; i
< m68hc11_num_opcodes
; i
++)
613 if (m68hc11_opcodes
[i
].arch
& current_architecture
)
615 opcodes
[num_opcodes
] = m68hc11_opcodes
[i
];
616 if (opcodes
[num_opcodes
].name
[0] == 'b'
617 && opcodes
[num_opcodes
].format
& M6811_OP_JUMP_REL
618 && !(opcodes
[num_opcodes
].format
& M6811_OP_BITMASK
))
621 opcodes
[num_opcodes
] = m68hc11_opcodes
[i
];
624 for (j
= 0; alias_opcodes
[j
].name
!= 0; j
++)
625 if (strcmp (m68hc11_opcodes
[i
].name
, alias_opcodes
[j
].name
) == 0)
627 opcodes
[num_opcodes
] = m68hc11_opcodes
[i
];
628 opcodes
[num_opcodes
].name
= alias_opcodes
[j
].alias
;
634 qsort (opcodes
, num_opcodes
, sizeof (struct m68hc11_opcode
),
635 (int (*) (const void*, const void*)) cmp_opcode
);
637 opc
= (struct m68hc11_opcode_def
*)
638 xmalloc (num_opcodes
* sizeof (struct m68hc11_opcode_def
));
639 m68hc11_opcode_defs
= opc
--;
641 /* Insert unique names into hash table. The M6811 instruction set
642 has several identical opcode names that have different opcodes based
643 on the operands. This hash table then provides a quick index to
644 the first opcode with a particular name in the opcode table. */
645 for (i
= 0; i
< num_opcodes
; i
++, opcodes
++)
649 if (strcmp (prev_name
, opcodes
->name
))
651 prev_name
= (char *) opcodes
->name
;
655 opc
->min_operands
= 100;
656 opc
->max_operands
= 0;
658 opc
->opcode
= opcodes
;
660 hash_insert (m68hc11_hash
, opcodes
->name
, opc
);
663 opc
->format
|= opcodes
->format
;
665 /* See how many operands this opcode needs. */
667 if (opcodes
->format
& M6811_OP_MASK
)
669 if (opcodes
->format
& M6811_OP_BITMASK
)
671 if (opcodes
->format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
673 if (opcodes
->format
& (M6812_OP_IND16_P2
| M6812_OP_IDX_P2
))
675 /* Special case for call instruction. */
676 if ((opcodes
->format
& M6812_OP_PAGE
)
677 && !(opcodes
->format
& M6811_OP_IND16
))
680 if (expect
< opc
->min_operands
)
681 opc
->min_operands
= expect
;
682 if (IS_CALL_SYMBOL (opcodes
->format
))
684 if (expect
> opc
->max_operands
)
685 opc
->max_operands
= expect
;
688 m68hc11_nb_opcode_defs
= opc
- m68hc11_opcode_defs
;
690 if (flag_print_opcodes
)
692 print_opcode_list ();
698 m68hc11_init_after_args (void)
704 /* Return a string that represents the operand format for the instruction.
705 When example is true, this generates an example of operand. This is used
706 to give an example and also to generate a test. */
708 print_opcode_format (struct m68hc11_opcode
*opcode
, int example
)
710 static char buf
[128];
711 int format
= opcode
->format
;
716 if (format
& M6811_OP_IMM8
)
719 sprintf (p
, "#%d", rand () & 0x0FF);
721 strcpy (p
, _("#<imm8>"));
725 if (format
& M6811_OP_IMM16
)
728 sprintf (p
, "#%d", rand () & 0x0FFFF);
730 strcpy (p
, _("#<imm16>"));
734 if (format
& M6811_OP_IX
)
737 sprintf (p
, "%d,X", rand () & 0x0FF);
739 strcpy (p
, _("<imm8>,X"));
743 if (format
& M6811_OP_IY
)
746 sprintf (p
, "%d,X", rand () & 0x0FF);
748 strcpy (p
, _("<imm8>,X"));
752 if (format
& M6812_OP_IDX
)
755 sprintf (p
, "%d,X", rand () & 0x0FF);
761 if (format
& M6812_OP_PAGE
)
764 sprintf (p
, ", %d", rand () & 0x0FF);
766 strcpy (p
, ", <page>");
770 if (format
& M6811_OP_DIRECT
)
773 sprintf (p
, "*Z%d", rand () & 0x0FF);
775 strcpy (p
, _("*<abs8>"));
779 if (format
& M6811_OP_BITMASK
)
785 sprintf (p
, "#$%02x", rand () & 0x0FF);
787 strcpy (p
, _("#<mask>"));
790 if (format
& M6811_OP_JUMP_REL
)
794 if (format
& M6811_OP_IND16
)
797 sprintf (p
, _("symbol%d"), rand () & 0x0FF);
799 strcpy (p
, _("<abs>"));
804 if (format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
808 if (format
& M6811_OP_BITMASK
)
810 sprintf (p
, ".+%d", rand () & 0x7F);
814 sprintf (p
, "L%d", rand () & 0x0FF);
818 strcpy (p
, _("<label>"));
824 /* Prints the list of instructions with the possible operands. */
826 print_opcode_list (void)
829 char *prev_name
= "";
830 struct m68hc11_opcode
*opcodes
;
831 int example
= flag_print_opcodes
== 2;
834 printf (_("# Example of `%s' instructions\n\t.sect .text\n_start:\n"),
837 opcodes
= m68hc11_sorted_opcodes
;
839 /* Walk the list sorted on names (by md_begin). We only report
840 one instruction per line, and we collect the different operand
842 for (i
= 0; i
< num_opcodes
; i
++, opcodes
++)
844 char *fmt
= print_opcode_format (opcodes
, example
);
848 printf ("L%d:\t", i
);
849 printf ("%s %s\n", opcodes
->name
, fmt
);
853 if (strcmp (prev_name
, opcodes
->name
))
858 printf ("%-5.5s ", opcodes
->name
);
859 prev_name
= (char *) opcodes
->name
;
862 printf (" [%s]", fmt
);
868 /* Print the instruction format. This operation is called when some
869 instruction is not correct. Instruction format is printed as an
872 print_insn_format (char *name
)
874 struct m68hc11_opcode_def
*opc
;
875 struct m68hc11_opcode
*opcode
;
878 opc
= (struct m68hc11_opcode_def
*) hash_find (m68hc11_hash
, name
);
881 as_bad (_("Instruction `%s' is not recognized."), name
);
884 opcode
= opc
->opcode
;
886 as_bad (_("Instruction formats for `%s':"), name
);
891 fmt
= print_opcode_format (opcode
, 0);
892 sprintf (buf
, "\t%-5.5s %s", opcode
->name
, fmt
);
897 while (strcmp (opcode
->name
, name
) == 0);
900 /* Analysis of 68HC11 and 68HC12 operands. */
902 /* reg_name_search() finds the register number given its name.
903 Returns the register number or REG_NONE on failure. */
905 reg_name_search (char *name
)
907 if (strcasecmp (name
, "x") == 0 || strcasecmp (name
, "ix") == 0)
909 if (strcasecmp (name
, "y") == 0 || strcasecmp (name
, "iy") == 0)
911 if (strcasecmp (name
, "a") == 0)
913 if (strcasecmp (name
, "b") == 0)
915 if (strcasecmp (name
, "d") == 0)
917 if (strcasecmp (name
, "sp") == 0)
919 if (strcasecmp (name
, "pc") == 0)
921 if (strcasecmp (name
, "ccr") == 0)
928 skip_whites (char *p
)
930 while (*p
== ' ' || *p
== '\t')
936 /* Check the string at input_line_pointer
937 to see if it is a valid register name. */
941 register_id reg_number
;
942 char c
, *p
= input_line_pointer
;
944 if (!is_name_beginner (*p
++))
947 while (is_part_of_name (*p
++))
954 /* Look to see if it's in the register table. */
955 reg_number
= reg_name_search (input_line_pointer
);
956 if (reg_number
!= REG_NONE
)
961 input_line_pointer
= p
;
969 #define M6811_OP_CALL_ADDR 0x00800000
970 #define M6811_OP_PAGE_ADDR 0x04000000
972 /* Parse a string of operands and return an array of expressions.
974 Operand mode[0] mode[1] exp[0] exp[1]
975 #n M6811_OP_IMM16 - O_*
976 *<exp> M6811_OP_DIRECT - O_*
977 .{+-}<exp> M6811_OP_JUMP_REL - O_*
978 <exp> M6811_OP_IND16 - O_*
979 ,r N,r M6812_OP_IDX M6812_OP_REG O_constant O_register
980 n,-r M6812_PRE_DEC M6812_OP_REG O_constant O_register
981 n,+r M6812_PRE_INC " "
982 n,r- M6812_POST_DEC " "
983 n,r+ M6812_POST_INC " "
984 A,r B,r D,r M6811_OP_REG M6812_OP_REG O_register O_register
985 [D,r] M6811_OP_D_IDX M6812_OP_REG O_register O_register
986 [n,r] M6811_OP_D_IDX_2 M6812_OP_REG O_constant O_register */
988 get_operand (operand
*oper
, int which
, long opmode
)
990 char *p
= input_line_pointer
;
994 oper
->exp
.X_op
= O_absent
;
995 oper
->reg1
= REG_NONE
;
996 oper
->reg2
= REG_NONE
;
997 mode
= M6811_OP_NONE
;
1001 if (*p
== 0 || *p
== '\n' || *p
== '\r')
1003 input_line_pointer
= p
;
1007 if (*p
== '*' && (opmode
& (M6811_OP_DIRECT
| M6811_OP_IND16
)))
1009 mode
= M6811_OP_DIRECT
;
1014 if (!(opmode
& (M6811_OP_IMM8
| M6811_OP_IMM16
| M6811_OP_BITMASK
)))
1016 as_bad (_("Immediate operand is not allowed for operand %d."),
1021 mode
= M6811_OP_IMM16
;
1023 if (strncmp (p
, "%hi", 3) == 0)
1026 mode
|= M6811_OP_HIGH_ADDR
;
1028 else if (strncmp (p
, "%lo", 3) == 0)
1031 mode
|= M6811_OP_LOW_ADDR
;
1033 /* %page modifier is used to obtain only the page number
1034 of the address of a function. */
1035 else if (strncmp (p
, "%page", 5) == 0)
1038 mode
|= M6811_OP_PAGE_ADDR
;
1041 /* %addr modifier is used to obtain the physical address part
1042 of the function (16-bit). For 68HC12 the function will be
1043 mapped in the 16K window at 0x8000 and the value will be
1044 within that window (although the function address may not fit
1045 in 16-bit). See bfd/elf32-m68hc12.c for the translation. */
1046 else if (strncmp (p
, "%addr", 5) == 0)
1049 mode
|= M6811_OP_CALL_ADDR
;
1052 else if (*p
== '.' && (p
[1] == '+' || p
[1] == '-'))
1055 mode
= M6811_OP_JUMP_REL
;
1059 if (current_architecture
& cpu6811
)
1060 as_bad (_("Indirect indexed addressing is not valid for 68HC11."));
1063 mode
= M6812_OP_D_IDX
;
1064 p
= skip_whites (p
);
1066 else if (*p
== ',') /* Special handling of ,x and ,y. */
1069 input_line_pointer
= p
;
1071 reg
= register_name ();
1072 if (reg
!= REG_NONE
)
1075 oper
->exp
.X_op
= O_constant
;
1076 oper
->exp
.X_add_number
= 0;
1077 oper
->mode
= M6812_OP_IDX
;
1080 as_bad (_("Spurious `,' or bad indirect register addressing mode."));
1083 /* Handle 68HC12 page specification in 'call foo,%page(bar)'. */
1084 else if ((opmode
& M6812_OP_PAGE
) && strncmp (p
, "%page", 5) == 0)
1087 mode
= M6811_OP_PAGE_ADDR
| M6812_OP_PAGE
| M6811_OP_IND16
;
1089 input_line_pointer
= p
;
1091 if (mode
== M6811_OP_NONE
|| mode
== M6812_OP_D_IDX
)
1092 reg
= register_name ();
1096 if (reg
!= REG_NONE
)
1098 p
= skip_whites (input_line_pointer
);
1099 if (*p
== ']' && mode
== M6812_OP_D_IDX
)
1102 (_("Missing second register or offset for indexed-indirect mode."));
1107 oper
->mode
= mode
| M6812_OP_REG
;
1110 if (mode
== M6812_OP_D_IDX
)
1112 as_bad (_("Missing second register for indexed-indirect mode."));
1119 input_line_pointer
= p
;
1120 reg
= register_name ();
1121 if (reg
!= REG_NONE
)
1123 p
= skip_whites (input_line_pointer
);
1124 if (mode
== M6812_OP_D_IDX
)
1128 as_bad (_("Missing `]' to close indexed-indirect mode."));
1132 oper
->mode
= M6812_OP_D_IDX
;
1134 input_line_pointer
= p
;
1142 /* In MRI mode, isolate the operand because we can't distinguish
1143 operands from comments. */
1148 p
= skip_whites (p
);
1149 while (*p
&& *p
!= ' ' && *p
!= '\t')
1158 /* Parse as an expression. */
1159 expression (&oper
->exp
);
1168 expression (&oper
->exp
);
1171 if (oper
->exp
.X_op
== O_illegal
)
1173 as_bad (_("Illegal operand."));
1176 else if (oper
->exp
.X_op
== O_absent
)
1178 as_bad (_("Missing operand."));
1182 p
= input_line_pointer
;
1184 if (mode
== M6811_OP_NONE
|| mode
== M6811_OP_DIRECT
1185 || mode
== M6812_OP_D_IDX
)
1187 p
= skip_whites (input_line_pointer
);
1191 int possible_mode
= M6811_OP_NONE
;
1192 char *old_input_line
;
1197 /* 68HC12 pre increment or decrement. */
1198 if (mode
== M6811_OP_NONE
)
1202 possible_mode
= M6812_PRE_DEC
;
1207 possible_mode
= M6812_PRE_INC
;
1210 p
= skip_whites (p
);
1212 input_line_pointer
= p
;
1213 reg
= register_name ();
1215 /* Backtrack if we have a valid constant expression and
1216 it does not correspond to the offset of the 68HC12 indexed
1217 addressing mode (as in N,x). */
1218 if (reg
== REG_NONE
&& mode
== M6811_OP_NONE
1219 && possible_mode
!= M6811_OP_NONE
)
1221 oper
->mode
= M6811_OP_IND16
| M6811_OP_JUMP_REL
;
1222 input_line_pointer
= skip_whites (old_input_line
);
1226 if (possible_mode
!= M6811_OP_NONE
)
1227 mode
= possible_mode
;
1229 if ((current_architecture
& cpu6811
)
1230 && possible_mode
!= M6811_OP_NONE
)
1231 as_bad (_("Pre-increment mode is not valid for 68HC11"));
1233 if (which
== 0 && opmode
& M6812_OP_IDX_P2
1234 && reg
!= REG_X
&& reg
!= REG_Y
1235 && reg
!= REG_PC
&& reg
!= REG_SP
)
1238 input_line_pointer
= p
;
1241 if (reg
== REG_NONE
&& mode
!= M6811_OP_DIRECT
1242 && !(mode
== M6811_OP_NONE
&& opmode
& M6811_OP_IND16
))
1244 as_bad (_("Wrong register in register indirect mode."));
1247 if (mode
== M6812_OP_D_IDX
)
1249 p
= skip_whites (input_line_pointer
);
1252 as_bad (_("Missing `]' to close register indirect operand."));
1255 input_line_pointer
= p
;
1257 oper
->mode
= M6812_OP_D_IDX_2
;
1260 if (reg
!= REG_NONE
)
1263 if (mode
== M6811_OP_NONE
)
1265 p
= input_line_pointer
;
1268 mode
= M6812_POST_DEC
;
1270 if (current_architecture
& cpu6811
)
1272 (_("Post-decrement mode is not valid for 68HC11."));
1276 mode
= M6812_POST_INC
;
1278 if (current_architecture
& cpu6811
)
1280 (_("Post-increment mode is not valid for 68HC11."));
1283 mode
= M6812_OP_IDX
;
1285 input_line_pointer
= p
;
1288 mode
|= M6812_OP_IDX
;
1293 input_line_pointer
= old_input_line
;
1296 if (mode
== M6812_OP_D_IDX_2
)
1298 as_bad (_("Invalid indexed indirect mode."));
1303 /* If the mode is not known until now, this is either a label
1304 or an indirect address. */
1305 if (mode
== M6811_OP_NONE
)
1306 mode
= M6811_OP_IND16
| M6811_OP_JUMP_REL
;
1308 p
= input_line_pointer
;
1309 while (*p
== ' ' || *p
== '\t')
1311 input_line_pointer
= p
;
1317 #define M6812_AUTO_INC_DEC (M6812_PRE_INC | M6812_PRE_DEC \
1318 | M6812_POST_INC | M6812_POST_DEC)
1320 /* Checks that the number 'num' fits for a given mode. */
1322 check_range (long num
, int mode
)
1324 /* Auto increment and decrement are ok for [-8..8] without 0. */
1325 if (mode
& M6812_AUTO_INC_DEC
)
1326 return (num
!= 0 && num
<= 8 && num
>= -8);
1328 /* The 68HC12 supports 5, 9 and 16-bit offsets. */
1329 if (mode
& (M6812_INDEXED_IND
| M6812_INDEXED
| M6812_OP_IDX
))
1330 mode
= M6811_OP_IND16
;
1332 if (mode
& M6812_OP_JUMP_REL16
)
1333 mode
= M6811_OP_IND16
;
1335 mode
&= ~M6811_OP_BRANCH
;
1340 case M6811_OP_DIRECT
:
1341 return (num
>= 0 && num
<= 255) ? 1 : 0;
1343 case M6811_OP_BITMASK
:
1346 return (((num
& 0xFFFFFF00) == 0) || ((num
& 0xFFFFFF00) == 0xFFFFFF00))
1349 case M6811_OP_JUMP_REL
:
1350 return (num
>= -128 && num
<= 127) ? 1 : 0;
1352 case M6811_OP_IND16
:
1353 case M6811_OP_IND16
| M6812_OP_PAGE
:
1354 case M6811_OP_IMM16
:
1355 return (((num
& 0xFFFF0000) == 0) || ((num
& 0xFFFF0000) == 0xFFFF0000))
1358 case M6812_OP_IBCC_MARKER
:
1359 case M6812_OP_TBCC_MARKER
:
1360 case M6812_OP_DBCC_MARKER
:
1361 return (num
>= -256 && num
<= 255) ? 1 : 0;
1363 case M6812_OP_TRAP_ID
:
1364 return ((num
>= 0x30 && num
<= 0x39)
1365 || (num
>= 0x40 && num
<= 0x0ff)) ? 1 : 0;
1372 /* Gas fixup generation. */
1374 /* Put a 1 byte expression described by 'oper'. If this expression contains
1375 unresolved symbols, generate an 8-bit fixup. */
1377 fixup8 (expressionS
*oper
, int mode
, int opmode
)
1383 if (oper
->X_op
== O_constant
)
1385 if (mode
& M6812_OP_TRAP_ID
1386 && !check_range (oper
->X_add_number
, M6812_OP_TRAP_ID
))
1388 static char trap_id_warn_once
= 0;
1390 as_bad (_("Trap id `%ld' is out of range."), oper
->X_add_number
);
1391 if (trap_id_warn_once
== 0)
1393 trap_id_warn_once
= 1;
1394 as_bad (_("Trap id must be within [0x30..0x39] or [0x40..0xff]."));
1398 if (!(mode
& M6812_OP_TRAP_ID
)
1399 && !check_range (oper
->X_add_number
, mode
))
1401 as_bad (_("Operand out of 8-bit range: `%ld'."), oper
->X_add_number
);
1403 number_to_chars_bigendian (f
, oper
->X_add_number
& 0x0FF, 1);
1405 else if (oper
->X_op
!= O_register
)
1407 if (mode
& M6812_OP_TRAP_ID
)
1408 as_bad (_("The trap id must be a constant."));
1410 if (mode
== M6811_OP_JUMP_REL
)
1414 fixp
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 1,
1415 oper
, TRUE
, BFD_RELOC_8_PCREL
);
1416 fixp
->fx_pcrel_adjust
= 1;
1423 /* Now create an 8-bit fixup. If there was some %hi, %lo
1424 or %page modifier, generate the reloc accordingly. */
1425 if (opmode
& M6811_OP_HIGH_ADDR
)
1426 reloc
= BFD_RELOC_M68HC11_HI8
;
1427 else if (opmode
& M6811_OP_LOW_ADDR
)
1428 reloc
= BFD_RELOC_M68HC11_LO8
;
1429 else if (opmode
& M6811_OP_PAGE_ADDR
)
1430 reloc
= BFD_RELOC_M68HC11_PAGE
;
1432 reloc
= BFD_RELOC_8
;
1434 fixp
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 1,
1435 oper
, FALSE
, reloc
);
1436 if (reloc
!= BFD_RELOC_8
)
1437 fixp
->fx_no_overflow
= 1;
1439 number_to_chars_bigendian (f
, 0, 1);
1443 as_fatal (_("Operand `%x' not recognized in fixup8."), oper
->X_op
);
1447 /* Put a 2 byte expression described by 'oper'. If this expression contains
1448 unresolved symbols, generate a 16-bit fixup. */
1450 fixup16 (expressionS
*oper
, int mode
, int opmode ATTRIBUTE_UNUSED
)
1456 if (oper
->X_op
== O_constant
)
1458 if (!check_range (oper
->X_add_number
, mode
))
1460 as_bad (_("Operand out of 16-bit range: `%ld'."),
1461 oper
->X_add_number
);
1463 number_to_chars_bigendian (f
, oper
->X_add_number
& 0x0FFFF, 2);
1465 else if (oper
->X_op
!= O_register
)
1470 if ((opmode
& M6811_OP_CALL_ADDR
) && (mode
& M6811_OP_IMM16
))
1471 reloc
= BFD_RELOC_M68HC11_LO16
;
1472 else if (mode
& M6812_OP_JUMP_REL16
)
1473 reloc
= BFD_RELOC_16_PCREL
;
1474 else if (mode
& M6812_OP_PAGE
)
1475 reloc
= BFD_RELOC_M68HC11_LO16
;
1477 reloc
= BFD_RELOC_16
;
1479 /* Now create a 16-bit fixup. */
1480 fixp
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 2,
1482 reloc
== BFD_RELOC_16_PCREL
,
1484 number_to_chars_bigendian (f
, 0, 2);
1485 if (reloc
== BFD_RELOC_16_PCREL
)
1486 fixp
->fx_pcrel_adjust
= 2;
1487 if (reloc
== BFD_RELOC_M68HC11_LO16
)
1488 fixp
->fx_no_overflow
= 1;
1492 as_fatal (_("Operand `%x' not recognized in fixup16."), oper
->X_op
);
1496 /* Put a 3 byte expression described by 'oper'. If this expression contains
1497 unresolved symbols, generate a 24-bit fixup. */
1499 fixup24 (expressionS
*oper
, int mode
, int opmode ATTRIBUTE_UNUSED
)
1505 if (oper
->X_op
== O_constant
)
1507 if (!check_range (oper
->X_add_number
, mode
))
1509 as_bad (_("Operand out of 16-bit range: `%ld'."),
1510 oper
->X_add_number
);
1512 number_to_chars_bigendian (f
, oper
->X_add_number
& 0x0FFFFFF, 3);
1514 else if (oper
->X_op
!= O_register
)
1518 /* Now create a 24-bit fixup. */
1519 fixp
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 2,
1520 oper
, FALSE
, BFD_RELOC_M68HC11_24
);
1521 number_to_chars_bigendian (f
, 0, 3);
1525 as_fatal (_("Operand `%x' not recognized in fixup16."), oper
->X_op
);
1529 /* 68HC11 and 68HC12 code generation. */
1531 /* Translate the short branch/bsr instruction into a long branch. */
1532 static unsigned char
1533 convert_branch (unsigned char code
)
1535 if (IS_OPCODE (code
, M6812_BSR
))
1537 else if (IS_OPCODE (code
, M6811_BSR
))
1539 else if (IS_OPCODE (code
, M6811_BRA
))
1540 return (current_architecture
& cpu6812
) ? M6812_JMP
: M6811_JMP
;
1542 as_fatal (_("Unexpected branch conversion with `%x'"), code
);
1544 /* Keep gcc happy. */
1548 /* Start a new insn that contains at least 'size' bytes. Record the
1549 line information of that insn in the dwarf2 debug sections. */
1551 m68hc11_new_insn (int size
)
1555 f
= frag_more (size
);
1557 dwarf2_emit_insn (size
);
1562 /* Builds a jump instruction (bra, bcc, bsr). */
1564 build_jump_insn (struct m68hc11_opcode
*opcode
, operand operands
[],
1565 int nb_operands
, int jmp_mode
)
1573 /* The relative branch conversion is not supported for
1575 assert ((opcode
->format
& M6811_OP_BITMASK
) == 0);
1576 assert (nb_operands
== 1);
1577 assert (operands
[0].reg1
== REG_NONE
&& operands
[0].reg2
== REG_NONE
);
1579 code
= opcode
->opcode
;
1581 n
= operands
[0].exp
.X_add_number
;
1583 /* Turn into a long branch:
1584 - when force long branch option (and not for jbcc pseudos),
1585 - when jbcc and the constant is out of -128..127 range,
1586 - when branch optimization is allowed and branch out of range. */
1587 if ((jmp_mode
== 0 && flag_force_long_jumps
)
1588 || (operands
[0].exp
.X_op
== O_constant
1589 && (!check_range (n
, opcode
->format
) &&
1590 (jmp_mode
== 1 || flag_fixed_branchs
== 0))))
1593 where
= frag_now_fix ();
1595 fix_new (frag_now
, frag_now_fix (), 1,
1596 &abs_symbol
, 0, 1, BFD_RELOC_M68HC11_RL_JUMP
);
1598 if (code
== M6811_BSR
|| code
== M6811_BRA
|| code
== M6812_BSR
)
1600 code
= convert_branch (code
);
1602 f
= m68hc11_new_insn (1);
1603 number_to_chars_bigendian (f
, code
, 1);
1605 else if (current_architecture
& cpu6812
)
1607 /* 68HC12: translate the bcc into a lbcc. */
1608 f
= m68hc11_new_insn (2);
1609 number_to_chars_bigendian (f
, M6811_OPCODE_PAGE2
, 1);
1610 number_to_chars_bigendian (f
+ 1, code
, 1);
1611 fixup16 (&operands
[0].exp
, M6812_OP_JUMP_REL16
,
1612 M6812_OP_JUMP_REL16
);
1617 /* 68HC11: translate the bcc into b!cc +3; jmp <L>. */
1618 f
= m68hc11_new_insn (3);
1620 number_to_chars_bigendian (f
, code
, 1);
1621 number_to_chars_bigendian (f
+ 1, 3, 1);
1622 number_to_chars_bigendian (f
+ 2, M6811_JMP
, 1);
1624 fixup16 (&operands
[0].exp
, M6811_OP_IND16
, M6811_OP_IND16
);
1628 /* Branch with a constant that must fit in 8-bits. */
1629 if (operands
[0].exp
.X_op
== O_constant
)
1631 if (!check_range (n
, opcode
->format
))
1633 as_bad (_("Operand out of range for a relative branch: `%ld'"),
1636 else if (opcode
->format
& M6812_OP_JUMP_REL16
)
1638 f
= m68hc11_new_insn (4);
1639 number_to_chars_bigendian (f
, M6811_OPCODE_PAGE2
, 1);
1640 number_to_chars_bigendian (f
+ 1, code
, 1);
1641 number_to_chars_bigendian (f
+ 2, n
& 0x0ffff, 2);
1645 f
= m68hc11_new_insn (2);
1646 number_to_chars_bigendian (f
, code
, 1);
1647 number_to_chars_bigendian (f
+ 1, n
& 0x0FF, 1);
1650 else if (opcode
->format
& M6812_OP_JUMP_REL16
)
1653 where
= frag_now_fix ();
1655 fix_new (frag_now
, frag_now_fix (), 1,
1656 &abs_symbol
, 0, 1, BFD_RELOC_M68HC11_RL_JUMP
);
1658 f
= m68hc11_new_insn (2);
1659 number_to_chars_bigendian (f
, M6811_OPCODE_PAGE2
, 1);
1660 number_to_chars_bigendian (f
+ 1, code
, 1);
1661 fixup16 (&operands
[0].exp
, M6812_OP_JUMP_REL16
, M6812_OP_JUMP_REL16
);
1668 where
= frag_now_fix ();
1670 fix_new (frag_now
, frag_now_fix (), 1,
1671 &abs_symbol
, 0, 1, BFD_RELOC_M68HC11_RL_JUMP
);
1673 /* Branch offset must fit in 8-bits, don't do some relax. */
1674 if (jmp_mode
== 0 && flag_fixed_branchs
)
1676 opcode
= m68hc11_new_insn (1);
1677 number_to_chars_bigendian (opcode
, code
, 1);
1678 fixup8 (&operands
[0].exp
, M6811_OP_JUMP_REL
, M6811_OP_JUMP_REL
);
1681 /* bra/bsr made be changed into jmp/jsr. */
1682 else if (code
== M6811_BSR
|| code
== M6811_BRA
|| code
== M6812_BSR
)
1684 /* Allocate worst case storage. */
1685 opcode
= m68hc11_new_insn (3);
1686 number_to_chars_bigendian (opcode
, code
, 1);
1687 number_to_chars_bigendian (opcode
+ 1, 0, 1);
1688 frag_variant (rs_machine_dependent
, 1, 1,
1689 ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_UNDF
),
1690 operands
[0].exp
.X_add_symbol
, (offsetT
) n
,
1693 else if (current_architecture
& cpu6812
)
1695 opcode
= m68hc11_new_insn (2);
1696 number_to_chars_bigendian (opcode
, code
, 1);
1697 number_to_chars_bigendian (opcode
+ 1, 0, 1);
1698 frag_var (rs_machine_dependent
, 2, 2,
1699 ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
, STATE_UNDF
),
1700 operands
[0].exp
.X_add_symbol
, (offsetT
) n
, opcode
);
1704 opcode
= m68hc11_new_insn (2);
1705 number_to_chars_bigendian (opcode
, code
, 1);
1706 number_to_chars_bigendian (opcode
+ 1, 0, 1);
1707 frag_var (rs_machine_dependent
, 3, 3,
1708 ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
, STATE_UNDF
),
1709 operands
[0].exp
.X_add_symbol
, (offsetT
) n
, opcode
);
1714 /* Builds a dbne/dbeq/tbne/tbeq instruction. */
1716 build_dbranch_insn (struct m68hc11_opcode
*opcode
, operand operands
[],
1717 int nb_operands
, int jmp_mode
)
1723 /* The relative branch conversion is not supported for
1725 assert ((opcode
->format
& M6811_OP_BITMASK
) == 0);
1726 assert (nb_operands
== 2);
1727 assert (operands
[0].reg1
!= REG_NONE
);
1729 code
= opcode
->opcode
& 0x0FF;
1731 f
= m68hc11_new_insn (1);
1732 number_to_chars_bigendian (f
, code
, 1);
1734 n
= operands
[1].exp
.X_add_number
;
1735 code
= operands
[0].reg1
;
1737 if (operands
[0].reg1
== REG_NONE
|| operands
[0].reg1
== REG_CCR
1738 || operands
[0].reg1
== REG_PC
)
1739 as_bad (_("Invalid register for dbcc/tbcc instruction."));
1741 if (opcode
->format
& M6812_OP_IBCC_MARKER
)
1743 else if (opcode
->format
& M6812_OP_TBCC_MARKER
)
1746 if (!(opcode
->format
& M6812_OP_EQ_MARKER
))
1749 /* Turn into a long branch:
1750 - when force long branch option (and not for jbcc pseudos),
1751 - when jdbcc and the constant is out of -256..255 range,
1752 - when branch optimization is allowed and branch out of range. */
1753 if ((jmp_mode
== 0 && flag_force_long_jumps
)
1754 || (operands
[1].exp
.X_op
== O_constant
1755 && (!check_range (n
, M6812_OP_IBCC_MARKER
) &&
1756 (jmp_mode
== 1 || flag_fixed_branchs
== 0))))
1760 number_to_chars_bigendian (f
, code
, 1);
1761 number_to_chars_bigendian (f
+ 1, M6812_JMP
, 1);
1762 fixup16 (&operands
[0].exp
, M6811_OP_IND16
, M6811_OP_IND16
);
1766 /* Branch with a constant that must fit in 9-bits. */
1767 if (operands
[1].exp
.X_op
== O_constant
)
1769 if (!check_range (n
, M6812_OP_IBCC_MARKER
))
1771 as_bad (_("Operand out of range for a relative branch: `%ld'"),
1780 number_to_chars_bigendian (f
, code
, 1);
1781 number_to_chars_bigendian (f
+ 1, n
& 0x0FF, 1);
1786 /* Branch offset must fit in 8-bits, don't do some relax. */
1787 if (jmp_mode
== 0 && flag_fixed_branchs
)
1789 fixup8 (&operands
[0].exp
, M6811_OP_JUMP_REL
, M6811_OP_JUMP_REL
);
1795 number_to_chars_bigendian (f
, code
, 1);
1796 number_to_chars_bigendian (f
+ 1, 0, 1);
1797 frag_var (rs_machine_dependent
, 3, 3,
1798 ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_UNDF
),
1799 operands
[1].exp
.X_add_symbol
, (offsetT
) n
, f
);
1804 #define OP_EXTENDED (M6811_OP_PAGE2 | M6811_OP_PAGE3 | M6811_OP_PAGE4)
1806 /* Assemble the post index byte for 68HC12 extended addressing modes. */
1808 build_indexed_byte (operand
*op
, int format ATTRIBUTE_UNUSED
, int move_insn
)
1810 unsigned char byte
= 0;
1815 val
= op
->exp
.X_add_number
;
1817 if (mode
& M6812_AUTO_INC_DEC
)
1820 if (mode
& (M6812_POST_INC
| M6812_POST_DEC
))
1823 if (op
->exp
.X_op
== O_constant
)
1825 if (!check_range (val
, mode
))
1827 as_bad (_("Increment/decrement value is out of range: `%ld'."),
1830 if (mode
& (M6812_POST_INC
| M6812_PRE_INC
))
1831 byte
|= (val
- 1) & 0x07;
1833 byte
|= (8 - ((val
) & 7)) | 0x8;
1838 as_fatal (_("Expecting a register."));
1853 as_bad (_("Invalid register for post/pre increment."));
1858 number_to_chars_bigendian (f
, byte
, 1);
1862 if (mode
& (M6812_OP_IDX
| M6812_OP_D_IDX_2
))
1883 as_bad (_("Invalid register."));
1886 if (op
->exp
.X_op
== O_constant
)
1888 if (!check_range (val
, M6812_OP_IDX
))
1890 as_bad (_("Offset out of 16-bit range: %ld."), val
);
1893 if (move_insn
&& !(val
>= -16 && val
<= 15))
1895 as_bad (_("Offset out of 5-bit range for movw/movb insn: %ld."),
1900 if (val
>= -16 && val
<= 15 && !(mode
& M6812_OP_D_IDX_2
))
1905 number_to_chars_bigendian (f
, byte
, 1);
1908 else if (val
>= -256 && val
<= 255 && !(mode
& M6812_OP_D_IDX_2
))
1915 number_to_chars_bigendian (f
, byte
, 1);
1916 number_to_chars_bigendian (f
+ 1, val
& 0x0FF, 1);
1922 if (mode
& M6812_OP_D_IDX_2
)
1928 number_to_chars_bigendian (f
, byte
, 1);
1929 number_to_chars_bigendian (f
+ 1, val
& 0x0FFFF, 2);
1933 if (mode
& M6812_OP_D_IDX_2
)
1935 byte
= (byte
<< 3) | 0xe3;
1937 number_to_chars_bigendian (f
, byte
, 1);
1939 fixup16 (&op
->exp
, 0, 0);
1941 else if (op
->reg1
!= REG_PC
)
1947 number_to_chars_bigendian (f
, byte
, 1);
1948 sym
= op
->exp
.X_add_symbol
;
1949 off
= op
->exp
.X_add_number
;
1950 if (op
->exp
.X_op
!= O_symbol
)
1952 sym
= make_expr_symbol (&op
->exp
);
1955 /* movb/movw cannot be relaxed. */
1959 number_to_chars_bigendian (f
, byte
, 1);
1960 fix_new (frag_now
, f
- frag_now
->fr_literal
, 1,
1961 sym
, off
, 0, BFD_RELOC_M68HC12_5B
);
1966 number_to_chars_bigendian (f
, byte
, 1);
1967 frag_var (rs_machine_dependent
, 2, 2,
1968 ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_UNDF
),
1975 /* movb/movw cannot be relaxed. */
1979 number_to_chars_bigendian (f
, byte
, 1);
1980 fix_new (frag_now
, f
- frag_now
->fr_literal
, 1,
1981 op
->exp
.X_add_symbol
, op
->exp
.X_add_number
, 0, BFD_RELOC_M68HC12_5B
);
1986 number_to_chars_bigendian (f
, byte
, 1);
1987 frag_var (rs_machine_dependent
, 2, 2,
1988 ENCODE_RELAX (STATE_INDEXED_PCREL
, STATE_UNDF
),
1989 op
->exp
.X_add_symbol
,
1990 op
->exp
.X_add_number
, f
);
1996 if (mode
& (M6812_OP_REG
| M6812_OP_D_IDX
))
1998 if (mode
& M6812_OP_D_IDX
)
2000 if (op
->reg1
!= REG_D
)
2001 as_bad (_("Expecting register D for indexed indirect mode."));
2003 as_bad (_("Indexed indirect mode is not allowed for movb/movw."));
2020 as_bad (_("Invalid accumulator register."));
2045 as_bad (_("Invalid indexed register."));
2049 number_to_chars_bigendian (f
, byte
, 1);
2053 as_fatal (_("Addressing mode not implemented yet."));
2057 /* Assemble the 68HC12 register mode byte. */
2059 build_reg_mode (operand
*op
, int format
)
2064 if (format
& M6812_OP_SEX_MARKER
2065 && op
->reg1
!= REG_A
&& op
->reg1
!= REG_B
&& op
->reg1
!= REG_CCR
)
2066 as_bad (_("Invalid source register for this instruction, use 'tfr'."));
2067 else if (op
->reg1
== REG_NONE
|| op
->reg1
== REG_PC
)
2068 as_bad (_("Invalid source register."));
2070 if (format
& M6812_OP_SEX_MARKER
2071 && op
->reg2
!= REG_D
2072 && op
->reg2
!= REG_X
&& op
->reg2
!= REG_Y
&& op
->reg2
!= REG_SP
)
2073 as_bad (_("Invalid destination register for this instruction, use 'tfr'."));
2074 else if (op
->reg2
== REG_NONE
|| op
->reg2
== REG_PC
)
2075 as_bad (_("Invalid destination register."));
2077 byte
= (op
->reg1
<< 4) | (op
->reg2
);
2078 if (format
& M6812_OP_EXG_MARKER
)
2082 number_to_chars_bigendian (f
, byte
, 1);
2086 /* build_insn takes a pointer to the opcode entry in the opcode table,
2087 the array of operand expressions and builds the corresponding instruction.
2088 This operation only deals with non relative jumps insn (need special
2091 build_insn (struct m68hc11_opcode
*opcode
, operand operands
[],
2092 int nb_operands ATTRIBUTE_UNUSED
)
2099 /* Put the page code instruction if there is one. */
2100 format
= opcode
->format
;
2102 if (format
& M6811_OP_BRANCH
)
2103 fix_new (frag_now
, frag_now_fix (), 1,
2104 &abs_symbol
, 0, 1, BFD_RELOC_M68HC11_RL_JUMP
);
2106 if (format
& OP_EXTENDED
)
2110 f
= m68hc11_new_insn (2);
2111 if (format
& M6811_OP_PAGE2
)
2112 page_code
= M6811_OPCODE_PAGE2
;
2113 else if (format
& M6811_OP_PAGE3
)
2114 page_code
= M6811_OPCODE_PAGE3
;
2116 page_code
= M6811_OPCODE_PAGE4
;
2118 number_to_chars_bigendian (f
, page_code
, 1);
2122 f
= m68hc11_new_insn (1);
2124 number_to_chars_bigendian (f
, opcode
->opcode
, 1);
2128 /* The 68HC12 movb and movw instructions are special. We have to handle
2129 them in a special way. */
2130 if (format
& (M6812_OP_IND16_P2
| M6812_OP_IDX_P2
))
2133 if (format
& M6812_OP_IDX
)
2135 build_indexed_byte (&operands
[0], format
, 1);
2137 format
&= ~M6812_OP_IDX
;
2139 if (format
& M6812_OP_IDX_P2
)
2141 build_indexed_byte (&operands
[1], format
, 1);
2143 format
&= ~M6812_OP_IDX_P2
;
2147 if (format
& (M6811_OP_DIRECT
| M6811_OP_IMM8
))
2149 fixup8 (&operands
[i
].exp
,
2150 format
& (M6811_OP_DIRECT
| M6811_OP_IMM8
| M6812_OP_TRAP_ID
),
2154 else if (IS_CALL_SYMBOL (format
) && nb_operands
== 1)
2156 format
&= ~M6812_OP_PAGE
;
2157 fixup24 (&operands
[i
].exp
, format
& M6811_OP_IND16
,
2161 else if (format
& (M6811_OP_IMM16
| M6811_OP_IND16
))
2163 fixup16 (&operands
[i
].exp
,
2164 format
& (M6811_OP_IMM16
| M6811_OP_IND16
| M6812_OP_PAGE
),
2168 else if (format
& (M6811_OP_IX
| M6811_OP_IY
))
2170 if ((format
& M6811_OP_IX
) && (operands
[0].reg1
!= REG_X
))
2171 as_bad (_("Invalid indexed register, expecting register X."));
2172 if ((format
& M6811_OP_IY
) && (operands
[0].reg1
!= REG_Y
))
2173 as_bad (_("Invalid indexed register, expecting register Y."));
2175 fixup8 (&operands
[0].exp
, M6811_OP_IX
, operands
[0].mode
);
2179 (M6812_OP_IDX
| M6812_OP_IDX_2
| M6812_OP_IDX_1
2180 | M6812_OP_D_IDX
| M6812_OP_D_IDX_2
))
2182 build_indexed_byte (&operands
[i
], format
, move_insn
);
2185 else if (format
& M6812_OP_REG
&& current_architecture
& cpu6812
)
2187 build_reg_mode (&operands
[i
], format
);
2190 if (format
& M6811_OP_BITMASK
)
2192 fixup8 (&operands
[i
].exp
, M6811_OP_BITMASK
, operands
[i
].mode
);
2195 if (format
& M6811_OP_JUMP_REL
)
2197 fixup8 (&operands
[i
].exp
, M6811_OP_JUMP_REL
, operands
[i
].mode
);
2199 else if (format
& M6812_OP_IND16_P2
)
2201 fixup16 (&operands
[1].exp
, M6811_OP_IND16
, operands
[1].mode
);
2203 if (format
& M6812_OP_PAGE
)
2205 fixup8 (&operands
[i
].exp
, M6812_OP_PAGE
, operands
[i
].mode
);
2209 /* Opcode identification and operand analysis. */
2211 /* find() gets a pointer to an entry in the opcode table. It must look at all
2212 opcodes with the same name and use the operands to choose the correct
2213 opcode. Returns the opcode pointer if there was a match and 0 if none. */
2214 static struct m68hc11_opcode
*
2215 find (struct m68hc11_opcode_def
*opc
, operand operands
[], int nb_operands
)
2218 struct m68hc11_opcode
*opcode
;
2219 struct m68hc11_opcode
*op_indirect
;
2222 opcode
= opc
->opcode
;
2224 /* Now search the opcode table table for one with operands
2225 that matches what we've got. We're only done if the operands matched so
2226 far AND there are no more to check. */
2227 for (pos
= match
= 0; match
== 0 && pos
< opc
->nb_modes
; pos
++, opcode
++)
2229 int poss_indirect
= 0;
2230 long format
= opcode
->format
;
2234 if (opcode
->format
& M6811_OP_MASK
)
2236 if (opcode
->format
& M6811_OP_BITMASK
)
2238 if (opcode
->format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
2240 if (opcode
->format
& (M6812_OP_IND16_P2
| M6812_OP_IDX_P2
))
2242 if ((opcode
->format
& M6812_OP_PAGE
)
2243 && (!IS_CALL_SYMBOL (opcode
->format
) || nb_operands
== 2))
2246 for (i
= 0; expect
== nb_operands
&& i
< nb_operands
; i
++)
2248 int mode
= operands
[i
].mode
;
2250 if (mode
& M6811_OP_IMM16
)
2253 (M6811_OP_IMM8
| M6811_OP_IMM16
| M6811_OP_BITMASK
))
2257 if (mode
== M6811_OP_DIRECT
)
2259 if (format
& M6811_OP_DIRECT
)
2262 /* If the operand is a page 0 operand, remember a
2263 possible <abs-16> addressing mode. We mark
2264 this and continue to check other operands. */
2265 if (format
& M6811_OP_IND16
2266 && flag_strict_direct_addressing
&& op_indirect
== 0)
2273 if (mode
& M6811_OP_IND16
)
2275 if (i
== 0 && (format
& M6811_OP_IND16
) != 0)
2277 if (i
!= 0 && (format
& M6812_OP_PAGE
) != 0)
2279 if (i
!= 0 && (format
& M6812_OP_IND16_P2
) != 0)
2281 if (i
== 0 && (format
& M6811_OP_BITMASK
))
2284 if (mode
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
2286 if (format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
2289 if (mode
& M6812_OP_REG
)
2292 && (format
& M6812_OP_REG
)
2293 && (operands
[i
].reg2
== REG_NONE
))
2296 && (format
& M6812_OP_REG
)
2297 && (format
& M6812_OP_REG_2
)
2298 && (operands
[i
].reg2
!= REG_NONE
))
2301 && (format
& M6812_OP_IDX
)
2302 && (operands
[i
].reg2
!= REG_NONE
))
2305 && (format
& M6812_OP_IDX
)
2306 && (format
& (M6812_OP_IND16_P2
| M6812_OP_IDX_P2
)))
2309 && (format
& M6812_OP_IDX_P2
))
2313 if (mode
& M6812_OP_IDX
)
2315 if (format
& M6811_OP_IX
&& operands
[i
].reg1
== REG_X
)
2317 if (format
& M6811_OP_IY
&& operands
[i
].reg1
== REG_Y
)
2320 && format
& (M6812_OP_IDX
| M6812_OP_IDX_1
| M6812_OP_IDX_2
)
2321 && (operands
[i
].reg1
== REG_X
2322 || operands
[i
].reg1
== REG_Y
2323 || operands
[i
].reg1
== REG_SP
2324 || operands
[i
].reg1
== REG_PC
))
2326 if (i
== 1 && format
& M6812_OP_IDX_P2
)
2329 if (mode
& format
& (M6812_OP_D_IDX
| M6812_OP_D_IDX_2
))
2334 if (mode
& M6812_AUTO_INC_DEC
)
2337 && format
& (M6812_OP_IDX
| M6812_OP_IDX_1
|
2340 if (i
== 1 && format
& M6812_OP_IDX_P2
)
2345 match
= i
== nb_operands
;
2347 /* Operands are ok but an operand uses page 0 addressing mode
2348 while the insn supports abs-16 mode. Keep a reference to this
2349 insns in case there is no insn supporting page 0 addressing. */
2350 if (match
&& poss_indirect
)
2352 op_indirect
= opcode
;
2359 /* Page 0 addressing is used but not supported by any insn.
2360 If absolute addresses are supported, we use that insn. */
2361 if (match
== 0 && op_indirect
)
2363 opcode
= op_indirect
;
2375 /* Find the real opcode and its associated operands. We use a progressive
2376 approach here. On entry, 'opc' points to the first opcode in the
2377 table that matches the opcode name in the source line. We try to
2378 isolate an operand, find a possible match in the opcode table.
2379 We isolate another operand if no match were found. The table 'operands'
2380 is filled while operands are recognized.
2382 Returns the opcode pointer that matches the opcode name in the
2383 source line and the associated operands. */
2384 static struct m68hc11_opcode
*
2385 find_opcode (struct m68hc11_opcode_def
*opc
, operand operands
[],
2388 struct m68hc11_opcode
*opcode
;
2391 if (opc
->max_operands
== 0)
2397 for (i
= 0; i
< opc
->max_operands
;)
2401 result
= get_operand (&operands
[i
], i
, opc
->format
);
2405 /* Special case where the bitmask of the bclr/brclr
2406 instructions is not introduced by #.
2407 Example: bclr 3,x $80. */
2408 if (i
== 1 && (opc
->format
& M6811_OP_BITMASK
)
2409 && (operands
[i
].mode
& M6811_OP_IND16
))
2411 operands
[i
].mode
= M6811_OP_IMM16
;
2416 if (i
>= opc
->min_operands
)
2418 opcode
= find (opc
, operands
, i
);
2420 /* Another special case for 'call foo,page' instructions.
2421 Since we support 'call foo' and 'call foo,page' we must look
2422 if the optional page specification is present otherwise we will
2423 assemble immediately and treat the page spec as garbage. */
2424 if (opcode
&& !(opcode
->format
& M6812_OP_PAGE
))
2427 if (opcode
&& *input_line_pointer
!= ',')
2431 if (*input_line_pointer
== ',')
2432 input_line_pointer
++;
2438 #define M6812_XBCC_MARKER (M6812_OP_TBCC_MARKER \
2439 | M6812_OP_DBCC_MARKER \
2440 | M6812_OP_IBCC_MARKER)
2442 /* Gas line assembler entry point. */
2444 /* This is the main entry point for the machine-dependent assembler. str
2445 points to a machine-dependent instruction. This function is supposed to
2446 emit the frags/bytes it assembles to. */
2448 md_assemble (char *str
)
2450 struct m68hc11_opcode_def
*opc
;
2451 struct m68hc11_opcode
*opcode
;
2453 unsigned char *op_start
, *op_end
;
2457 operand operands
[M6811_MAX_OPERANDS
];
2459 int branch_optimize
= 0;
2462 /* Drop leading whitespace. */
2466 /* Find the opcode end and get the opcode in 'name'. The opcode is forced
2467 lower case (the opcode table only has lower case op-codes). */
2468 for (op_start
= op_end
= (unsigned char *) str
;
2469 *op_end
&& nlen
< 20 && !is_end_of_line
[*op_end
] && *op_end
!= ' ';
2472 name
[nlen
] = TOLOWER (op_start
[nlen
]);
2479 as_bad (_("No instruction or missing opcode."));
2483 /* Find the opcode definition given its name. */
2484 opc
= (struct m68hc11_opcode_def
*) hash_find (m68hc11_hash
, name
);
2486 /* If it's not recognized, look for 'jbsr' and 'jbxx'. These are
2487 pseudo insns for relative branch. For these branchs, we always
2488 optimize them (turned into absolute branchs) even if --short-branchs
2490 if (opc
== NULL
&& name
[0] == 'j' && name
[1] == 'b')
2492 opc
= (struct m68hc11_opcode_def
*) hash_find (m68hc11_hash
, &name
[1]);
2494 && (!(opc
->format
& M6811_OP_JUMP_REL
)
2495 || (opc
->format
& M6811_OP_BITMASK
)))
2498 branch_optimize
= 1;
2501 /* The following test should probably be removed. This is not conform
2502 to Motorola assembler specs. */
2503 if (opc
== NULL
&& flag_mri
)
2505 if (*op_end
== ' ' || *op_end
== '\t')
2507 while (*op_end
== ' ' || *op_end
== '\t')
2512 (is_end_of_line
[op_end
[1]]
2513 || op_end
[1] == ' ' || op_end
[1] == '\t'
2514 || !ISALNUM (op_end
[1])))
2515 && (*op_end
== 'a' || *op_end
== 'b'
2516 || *op_end
== 'A' || *op_end
== 'B'
2517 || *op_end
== 'd' || *op_end
== 'D'
2518 || *op_end
== 'x' || *op_end
== 'X'
2519 || *op_end
== 'y' || *op_end
== 'Y'))
2521 name
[nlen
++] = TOLOWER (*op_end
++);
2523 opc
= (struct m68hc11_opcode_def
*) hash_find (m68hc11_hash
,
2529 /* Identify a possible instruction alias. There are some on the
2530 68HC12 to emulate a few 68HC11 instructions. */
2531 if (opc
== NULL
&& (current_architecture
& cpu6812
))
2535 for (i
= 0; i
< m68hc12_num_alias
; i
++)
2536 if (strcmp (m68hc12_alias
[i
].name
, name
) == 0)
2542 if (opc
== NULL
&& alias_id
< 0)
2544 as_bad (_("Opcode `%s' is not recognized."), name
);
2547 save
= input_line_pointer
;
2548 input_line_pointer
= (char *) op_end
;
2553 opcode
= find_opcode (opc
, operands
, &nb_operands
);
2558 if ((opcode
|| alias_id
>= 0) && !flag_mri
)
2560 char *p
= input_line_pointer
;
2562 while (*p
== ' ' || *p
== '\t' || *p
== '\n' || *p
== '\r')
2565 if (*p
!= '\n' && *p
)
2566 as_bad (_("Garbage at end of instruction: `%s'."), p
);
2569 input_line_pointer
= save
;
2573 char *f
= m68hc11_new_insn (m68hc12_alias
[alias_id
].size
);
2575 number_to_chars_bigendian (f
, m68hc12_alias
[alias_id
].code1
, 1);
2576 if (m68hc12_alias
[alias_id
].size
> 1)
2577 number_to_chars_bigendian (f
+ 1, m68hc12_alias
[alias_id
].code2
, 1);
2582 /* Opcode is known but does not have valid operands. Print out the
2583 syntax for this opcode. */
2586 if (flag_print_insn_syntax
)
2587 print_insn_format (name
);
2589 as_bad (_("Invalid operand for `%s'"), name
);
2593 /* Treat dbeq/ibeq/tbeq instructions in a special way. The branch is
2594 relative and must be in the range -256..255 (9-bits). */
2595 if ((opcode
->format
& M6812_XBCC_MARKER
)
2596 && (opcode
->format
& M6811_OP_JUMP_REL
))
2597 build_dbranch_insn (opcode
, operands
, nb_operands
, branch_optimize
);
2599 /* Relative jumps instructions are taken care of separately. We have to make
2600 sure that the relative branch is within the range -128..127. If it's out
2601 of range, the instructions are changed into absolute instructions.
2602 This is not supported for the brset and brclr instructions. */
2603 else if ((opcode
->format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
2604 && !(opcode
->format
& M6811_OP_BITMASK
))
2605 build_jump_insn (opcode
, operands
, nb_operands
, branch_optimize
);
2607 build_insn (opcode
, operands
, nb_operands
);
2611 /* Pseudo op to control the ELF flags. */
2613 s_m68hc11_mode (int x ATTRIBUTE_UNUSED
)
2615 char *name
= input_line_pointer
, ch
;
2617 while (!is_end_of_line
[(unsigned char) *input_line_pointer
])
2618 input_line_pointer
++;
2619 ch
= *input_line_pointer
;
2620 *input_line_pointer
= '\0';
2622 if (strcmp (name
, "mshort") == 0)
2624 elf_flags
&= ~E_M68HC11_I32
;
2626 else if (strcmp (name
, "mlong") == 0)
2628 elf_flags
|= E_M68HC11_I32
;
2630 else if (strcmp (name
, "mshort-double") == 0)
2632 elf_flags
&= ~E_M68HC11_F64
;
2634 else if (strcmp (name
, "mlong-double") == 0)
2636 elf_flags
|= E_M68HC11_F64
;
2640 as_warn (_("Invalid mode: %s\n"), name
);
2642 *input_line_pointer
= ch
;
2643 demand_empty_rest_of_line ();
2646 /* Mark the symbols with STO_M68HC12_FAR to indicate the functions
2647 are using 'rtc' for returning. It is necessary to use 'call'
2648 to invoke them. This is also used by the debugger to correctly
2649 find the stack frame. */
2651 s_m68hc11_mark_symbol (int mark
)
2657 elf_symbol_type
*elfsym
;
2661 name
= input_line_pointer
;
2662 c
= get_symbol_end ();
2663 symbolP
= symbol_find_or_make (name
);
2664 *input_line_pointer
= c
;
2668 bfdsym
= symbol_get_bfdsym (symbolP
);
2669 elfsym
= elf_symbol_from (bfd_asymbol_bfd (bfdsym
), bfdsym
);
2673 /* Mark the symbol far (using rtc for function return). */
2674 elfsym
->internal_elf_sym
.st_other
|= mark
;
2678 input_line_pointer
++;
2682 if (*input_line_pointer
== '\n')
2688 demand_empty_rest_of_line ();
2692 s_m68hc11_relax (int ignore ATTRIBUTE_UNUSED
)
2698 if (ex
.X_op
!= O_symbol
|| ex
.X_add_number
!= 0)
2700 as_bad (_("bad .relax format"));
2701 ignore_rest_of_line ();
2705 fix_new_exp (frag_now
, frag_now_fix (), 2, &ex
, 1,
2706 BFD_RELOC_M68HC11_RL_GROUP
);
2708 demand_empty_rest_of_line ();
2712 /* Relocation, relaxation and frag conversions. */
2714 /* PC-relative offsets are relative to the start of the
2715 next instruction. That is, the address of the offset, plus its
2716 size, since the offset is always the last part of the insn. */
2718 md_pcrel_from (fixS
*fixP
)
2720 if (fixP
->fx_r_type
== BFD_RELOC_M68HC11_RL_JUMP
)
2723 return fixP
->fx_size
+ fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
2726 /* If while processing a fixup, a reloc really needs to be created
2727 then it is done here. */
2729 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
, fixS
*fixp
)
2733 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
2734 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
2735 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
2736 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
2737 if (fixp
->fx_r_type
== 0)
2738 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_16
);
2740 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
2741 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
2743 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2744 _("Relocation %d is not supported by object file format."),
2745 (int) fixp
->fx_r_type
);
2749 /* Since we use Rel instead of Rela, encode the vtable entry to be
2750 used in the relocation's section offset. */
2751 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
2752 reloc
->address
= fixp
->fx_offset
;
2758 /* We need a port-specific relaxation function to cope with sym2 - sym1
2759 relative expressions with both symbols in the same segment (but not
2760 necessarily in the same frag as this insn), for example:
2761 ldab sym2-(sym1-2),pc
2763 The offset can be 5, 9 or 16 bits long. */
2766 m68hc11_relax_frag (segT seg ATTRIBUTE_UNUSED
, fragS
*fragP
,
2767 long stretch ATTRIBUTE_UNUSED
)
2772 const relax_typeS
*this_type
;
2773 const relax_typeS
*start_type
;
2774 relax_substateT next_state
;
2775 relax_substateT this_state
;
2776 const relax_typeS
*table
= TC_GENERIC_RELAX_TABLE
;
2778 /* We only have to cope with frags as prepared by
2779 md_estimate_size_before_relax. The STATE_BITS16 case may geet here
2780 because of the different reasons that it's not relaxable. */
2781 switch (fragP
->fr_subtype
)
2783 case ENCODE_RELAX (STATE_INDEXED_PCREL
, STATE_BITS16
):
2784 case ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS16
):
2785 /* When we get to this state, the frag won't grow any more. */
2788 case ENCODE_RELAX (STATE_INDEXED_PCREL
, STATE_BITS5
):
2789 case ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS5
):
2790 case ENCODE_RELAX (STATE_INDEXED_PCREL
, STATE_BITS9
):
2791 case ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS9
):
2792 if (fragP
->fr_symbol
== NULL
2793 || S_GET_SEGMENT (fragP
->fr_symbol
) != absolute_section
)
2794 as_fatal (_("internal inconsistency problem in %s: fr_symbol %lx"),
2795 __FUNCTION__
, (long) fragP
->fr_symbol
);
2796 symbolP
= fragP
->fr_symbol
;
2797 if (symbol_resolved_p (symbolP
))
2798 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
2800 aim
= S_GET_VALUE (symbolP
);
2804 as_fatal (_("internal inconsistency problem in %s: fr_subtype %d"),
2805 __FUNCTION__
, fragP
->fr_subtype
);
2808 /* The rest is stolen from relax_frag. There's no obvious way to
2809 share the code, but fortunately no requirement to keep in sync as
2810 long as fragP->fr_symbol does not have its segment changed. */
2812 this_state
= fragP
->fr_subtype
;
2813 start_type
= this_type
= table
+ this_state
;
2817 /* Look backwards. */
2818 for (next_state
= this_type
->rlx_more
; next_state
;)
2819 if (aim
>= this_type
->rlx_backward
)
2823 /* Grow to next state. */
2824 this_state
= next_state
;
2825 this_type
= table
+ this_state
;
2826 next_state
= this_type
->rlx_more
;
2831 /* Look forwards. */
2832 for (next_state
= this_type
->rlx_more
; next_state
;)
2833 if (aim
<= this_type
->rlx_forward
)
2837 /* Grow to next state. */
2838 this_state
= next_state
;
2839 this_type
= table
+ this_state
;
2840 next_state
= this_type
->rlx_more
;
2844 growth
= this_type
->rlx_length
- start_type
->rlx_length
;
2846 fragP
->fr_subtype
= this_state
;
2851 md_convert_frag (bfd
*abfd ATTRIBUTE_UNUSED
, asection
*sec ATTRIBUTE_UNUSED
,
2857 char *buffer_address
= fragP
->fr_literal
;
2859 /* Address in object code of the displacement. */
2860 register int object_address
= fragP
->fr_fix
+ fragP
->fr_address
;
2862 buffer_address
+= fragP
->fr_fix
;
2864 /* The displacement of the address, from current location. */
2865 value
= S_GET_VALUE (fragP
->fr_symbol
);
2866 disp
= (value
+ fragP
->fr_offset
) - object_address
;
2868 switch (fragP
->fr_subtype
)
2870 case ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_BYTE
):
2871 fragP
->fr_opcode
[1] = disp
;
2874 case ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_WORD
):
2875 /* This relax is only for bsr and bra. */
2876 assert (IS_OPCODE (fragP
->fr_opcode
[0], M6811_BSR
)
2877 || IS_OPCODE (fragP
->fr_opcode
[0], M6811_BRA
)
2878 || IS_OPCODE (fragP
->fr_opcode
[0], M6812_BSR
));
2880 fragP
->fr_opcode
[0] = convert_branch (fragP
->fr_opcode
[0]);
2882 fix_new (fragP
, fragP
->fr_fix
- 1, 2,
2883 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_16
);
2887 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
, STATE_BYTE
):
2888 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
, STATE_BYTE
):
2889 fragP
->fr_opcode
[1] = disp
;
2892 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
, STATE_WORD
):
2893 /* Invert branch. */
2894 fragP
->fr_opcode
[0] ^= 1;
2895 fragP
->fr_opcode
[1] = 3; /* Branch offset. */
2896 buffer_address
[0] = M6811_JMP
;
2897 fix_new (fragP
, fragP
->fr_fix
+ 1, 2,
2898 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_16
);
2902 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
, STATE_WORD
):
2903 /* Translate branch into a long branch. */
2904 fragP
->fr_opcode
[1] = fragP
->fr_opcode
[0];
2905 fragP
->fr_opcode
[0] = M6811_OPCODE_PAGE2
;
2907 fixp
= fix_new (fragP
, fragP
->fr_fix
, 2,
2908 fragP
->fr_symbol
, fragP
->fr_offset
, 1,
2909 BFD_RELOC_16_PCREL
);
2910 fixp
->fx_pcrel_adjust
= 2;
2914 case ENCODE_RELAX (STATE_INDEXED_PCREL
, STATE_BITS5
):
2915 if (fragP
->fr_symbol
!= 0
2916 && S_GET_SEGMENT (fragP
->fr_symbol
) != absolute_section
)
2920 case ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS5
):
2921 fragP
->fr_opcode
[0] = fragP
->fr_opcode
[0] << 6;
2922 fragP
->fr_opcode
[0] |= value
& 0x1f;
2925 case ENCODE_RELAX (STATE_INDEXED_PCREL
, STATE_BITS9
):
2926 /* For a PC-relative offset, use the displacement with a -1 correction
2927 to take into account the additional byte of the insn. */
2928 if (fragP
->fr_symbol
!= 0
2929 && S_GET_SEGMENT (fragP
->fr_symbol
) != absolute_section
)
2933 case ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS9
):
2934 fragP
->fr_opcode
[0] = (fragP
->fr_opcode
[0] << 3);
2935 fragP
->fr_opcode
[0] |= 0xE0;
2936 fragP
->fr_opcode
[0] |= (value
>> 8) & 1;
2937 fragP
->fr_opcode
[1] = value
;
2941 case ENCODE_RELAX (STATE_INDEXED_PCREL
, STATE_BITS16
):
2942 case ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS16
):
2943 fragP
->fr_opcode
[0] = (fragP
->fr_opcode
[0] << 3);
2944 fragP
->fr_opcode
[0] |= 0xe2;
2945 if ((fragP
->fr_opcode
[0] & 0x0ff) == 0x0fa
2946 && fragP
->fr_symbol
!= 0
2947 && S_GET_SEGMENT (fragP
->fr_symbol
) != absolute_section
)
2949 fixp
= fix_new (fragP
, fragP
->fr_fix
, 2,
2950 fragP
->fr_symbol
, fragP
->fr_offset
,
2951 1, BFD_RELOC_16_PCREL
);
2955 fix_new (fragP
, fragP
->fr_fix
, 2,
2956 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_16
);
2961 case ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_BYTE
):
2963 fragP
->fr_opcode
[0] |= 0x10;
2965 fragP
->fr_opcode
[1] = disp
& 0x0FF;
2968 case ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_WORD
):
2969 /* Invert branch. */
2970 fragP
->fr_opcode
[0] ^= 0x20;
2971 fragP
->fr_opcode
[1] = 3; /* Branch offset. */
2972 buffer_address
[0] = M6812_JMP
;
2973 fix_new (fragP
, fragP
->fr_fix
+ 1, 2,
2974 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_16
);
2983 /* On an ELF system, we can't relax a weak symbol. The weak symbol
2984 can be overridden at final link time by a non weak symbol. We can
2985 relax externally visible symbol because there is no shared library
2986 and such symbol can't be overridden (unless they are weak). */
2988 relaxable_symbol (symbolS
*symbol
)
2990 return ! S_IS_WEAK (symbol
);
2993 /* Force truly undefined symbols to their maximum size, and generally set up
2994 the frag list to be relaxed. */
2996 md_estimate_size_before_relax (fragS
*fragP
, asection
*segment
)
2998 if (RELAX_LENGTH (fragP
->fr_subtype
) == STATE_UNDF
)
3000 if (S_GET_SEGMENT (fragP
->fr_symbol
) != segment
3001 || !relaxable_symbol (fragP
->fr_symbol
)
3002 || (segment
!= absolute_section
3003 && RELAX_STATE (fragP
->fr_subtype
) == STATE_INDEXED_OFFSET
))
3005 /* Non-relaxable cases. */
3007 char *buffer_address
;
3009 old_fr_fix
= fragP
->fr_fix
;
3010 buffer_address
= fragP
->fr_fix
+ fragP
->fr_literal
;
3012 switch (RELAX_STATE (fragP
->fr_subtype
))
3014 case STATE_PC_RELATIVE
:
3016 /* This relax is only for bsr and bra. */
3017 assert (IS_OPCODE (fragP
->fr_opcode
[0], M6811_BSR
)
3018 || IS_OPCODE (fragP
->fr_opcode
[0], M6811_BRA
)
3019 || IS_OPCODE (fragP
->fr_opcode
[0], M6812_BSR
));
3021 if (flag_fixed_branchs
)
3022 as_bad_where (fragP
->fr_file
, fragP
->fr_line
,
3023 _("bra or bsr with undefined symbol."));
3025 /* The symbol is undefined or in a separate section.
3026 Turn bra into a jmp and bsr into a jsr. The insn
3027 becomes 3 bytes long (instead of 2). A fixup is
3028 necessary for the unresolved symbol address. */
3029 fragP
->fr_opcode
[0] = convert_branch (fragP
->fr_opcode
[0]);
3031 fix_new (fragP
, fragP
->fr_fix
- 1, 2, fragP
->fr_symbol
,
3032 fragP
->fr_offset
, 0, BFD_RELOC_16
);
3036 case STATE_CONDITIONAL_BRANCH
:
3037 assert (current_architecture
& cpu6811
);
3039 fragP
->fr_opcode
[0] ^= 1; /* Reverse sense of branch. */
3040 fragP
->fr_opcode
[1] = 3; /* Skip next jmp insn (3 bytes). */
3042 /* Don't use fr_opcode[2] because this may be
3043 in a different frag. */
3044 buffer_address
[0] = M6811_JMP
;
3047 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
3048 fragP
->fr_offset
, 0, BFD_RELOC_16
);
3052 case STATE_INDEXED_OFFSET
:
3053 assert (current_architecture
& cpu6812
);
3055 if (fragP
->fr_symbol
3056 && S_GET_SEGMENT (fragP
->fr_symbol
) == absolute_section
)
3058 fragP
->fr_subtype
= ENCODE_RELAX (STATE_INDEXED_OFFSET
,
3060 /* Return the size of the variable part of the frag. */
3061 return md_relax_table
[fragP
->fr_subtype
].rlx_length
;
3065 /* Switch the indexed operation to 16-bit mode. */
3066 fragP
->fr_opcode
[0] = fragP
->fr_opcode
[0] << 3;
3067 fragP
->fr_opcode
[0] |= 0xe2;
3068 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
3069 fragP
->fr_offset
, 0, BFD_RELOC_16
);
3074 case STATE_INDEXED_PCREL
:
3075 assert (current_architecture
& cpu6812
);
3077 if (fragP
->fr_symbol
3078 && S_GET_SEGMENT (fragP
->fr_symbol
) == absolute_section
)
3080 fragP
->fr_subtype
= ENCODE_RELAX (STATE_INDEXED_PCREL
,
3082 /* Return the size of the variable part of the frag. */
3083 return md_relax_table
[fragP
->fr_subtype
].rlx_length
;
3089 fragP
->fr_opcode
[0] = fragP
->fr_opcode
[0] << 3;
3090 fragP
->fr_opcode
[0] |= 0xe2;
3091 fixp
= fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
3092 fragP
->fr_offset
, 1, BFD_RELOC_16_PCREL
);
3097 case STATE_XBCC_BRANCH
:
3098 assert (current_architecture
& cpu6812
);
3100 fragP
->fr_opcode
[0] ^= 0x20; /* Reverse sense of branch. */
3101 fragP
->fr_opcode
[1] = 3; /* Skip next jmp insn (3 bytes). */
3103 /* Don't use fr_opcode[2] because this may be
3104 in a different frag. */
3105 buffer_address
[0] = M6812_JMP
;
3108 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
3109 fragP
->fr_offset
, 0, BFD_RELOC_16
);
3113 case STATE_CONDITIONAL_BRANCH_6812
:
3114 assert (current_architecture
& cpu6812
);
3116 /* Translate into a lbcc branch. */
3117 fragP
->fr_opcode
[1] = fragP
->fr_opcode
[0];
3118 fragP
->fr_opcode
[0] = M6811_OPCODE_PAGE2
;
3120 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
3121 fragP
->fr_offset
, 1, BFD_RELOC_16_PCREL
);
3126 as_fatal (_("Subtype %d is not recognized."), fragP
->fr_subtype
);
3130 /* Return the growth in the fixed part of the frag. */
3131 return fragP
->fr_fix
- old_fr_fix
;
3134 /* Relaxable cases. */
3135 switch (RELAX_STATE (fragP
->fr_subtype
))
3137 case STATE_PC_RELATIVE
:
3138 /* This relax is only for bsr and bra. */
3139 assert (IS_OPCODE (fragP
->fr_opcode
[0], M6811_BSR
)
3140 || IS_OPCODE (fragP
->fr_opcode
[0], M6811_BRA
)
3141 || IS_OPCODE (fragP
->fr_opcode
[0], M6812_BSR
));
3143 fragP
->fr_subtype
= ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_BYTE
);
3146 case STATE_CONDITIONAL_BRANCH
:
3147 assert (current_architecture
& cpu6811
);
3149 fragP
->fr_subtype
= ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
,
3153 case STATE_INDEXED_OFFSET
:
3154 assert (current_architecture
& cpu6812
);
3156 fragP
->fr_subtype
= ENCODE_RELAX (STATE_INDEXED_OFFSET
,
3160 case STATE_INDEXED_PCREL
:
3161 assert (current_architecture
& cpu6812
);
3163 fragP
->fr_subtype
= ENCODE_RELAX (STATE_INDEXED_PCREL
,
3167 case STATE_XBCC_BRANCH
:
3168 assert (current_architecture
& cpu6812
);
3170 fragP
->fr_subtype
= ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_BYTE
);
3173 case STATE_CONDITIONAL_BRANCH_6812
:
3174 assert (current_architecture
& cpu6812
);
3176 fragP
->fr_subtype
= ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
,
3182 if (fragP
->fr_subtype
>= sizeof (md_relax_table
) / sizeof (md_relax_table
[0]))
3183 as_fatal (_("Subtype %d is not recognized."), fragP
->fr_subtype
);
3185 /* Return the size of the variable part of the frag. */
3186 return md_relax_table
[fragP
->fr_subtype
].rlx_length
;
3189 /* See whether we need to force a relocation into the output file. */
3191 tc_m68hc11_force_relocation (fixS
*fixP
)
3193 if (fixP
->fx_r_type
== BFD_RELOC_M68HC11_RL_GROUP
)
3196 return generic_force_reloc (fixP
);
3199 /* Here we decide which fixups can be adjusted to make them relative
3200 to the beginning of the section instead of the symbol. Basically
3201 we need to make sure that the linker relaxation is done
3202 correctly, so in some cases we force the original symbol to be
3205 tc_m68hc11_fix_adjustable (fixS
*fixP
)
3207 switch (fixP
->fx_r_type
)
3209 /* For the linker relaxation to work correctly, these relocs
3210 need to be on the symbol itself. */
3212 case BFD_RELOC_M68HC11_RL_JUMP
:
3213 case BFD_RELOC_M68HC11_RL_GROUP
:
3214 case BFD_RELOC_VTABLE_INHERIT
:
3215 case BFD_RELOC_VTABLE_ENTRY
:
3218 /* The memory bank addressing translation also needs the original
3220 case BFD_RELOC_M68HC11_LO16
:
3221 case BFD_RELOC_M68HC11_PAGE
:
3222 case BFD_RELOC_M68HC11_24
:
3231 md_apply_fix3 (fixS
*fixP
, valueT
*valP
, segT seg ATTRIBUTE_UNUSED
)
3234 long value
= * valP
;
3237 if (fixP
->fx_addsy
== (symbolS
*) NULL
)
3240 /* We don't actually support subtracting a symbol. */
3241 if (fixP
->fx_subsy
!= (symbolS
*) NULL
)
3242 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("Expression too complex."));
3244 op_type
= fixP
->fx_r_type
;
3246 /* Patch the instruction with the resolved operand. Elf relocation
3247 info will also be generated to take care of linker/loader fixups.
3248 The 68HC11 addresses only 64Kb, we are only concerned by 8 and 16-bit
3249 relocs. BFD_RELOC_8 is basically used for .page0 access (the linker
3250 will warn for overflows). BFD_RELOC_8_PCREL should not be generated
3251 because it's either resolved or turned out into non-relative insns (see
3252 relax table, bcc, bra, bsr transformations)
3254 The BFD_RELOC_32 is necessary for the support of --gstabs. */
3255 where
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
3257 switch (fixP
->fx_r_type
)
3260 bfd_putb32 ((bfd_vma
) value
, (unsigned char *) where
);
3264 case BFD_RELOC_M68HC11_24
:
3265 bfd_putb16 ((bfd_vma
) (value
& 0x0ffff), (unsigned char *) where
);
3266 ((bfd_byte
*) where
)[2] = ((value
>> 16) & 0x0ff);
3270 case BFD_RELOC_16_PCREL
:
3271 case BFD_RELOC_M68HC11_LO16
:
3272 bfd_putb16 ((bfd_vma
) value
, (unsigned char *) where
);
3273 if (value
< -65537 || value
> 65535)
3274 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3275 _("Value out of 16-bit range."));
3278 case BFD_RELOC_M68HC11_HI8
:
3282 case BFD_RELOC_M68HC11_LO8
:
3284 case BFD_RELOC_M68HC11_PAGE
:
3285 ((bfd_byte
*) where
)[0] = (bfd_byte
) value
;
3288 case BFD_RELOC_8_PCREL
:
3289 ((bfd_byte
*) where
)[0] = (bfd_byte
) value
;
3291 if (value
< -128 || value
> 127)
3292 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3293 _("Value %ld too large for 8-bit PC-relative branch."),
3297 case BFD_RELOC_M68HC11_3B
:
3298 if (value
<= 0 || value
> 8)
3299 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3300 _("Auto increment/decrement offset '%ld' is out of range."),
3307 where
[0] = where
[0] | (value
& 0x07);
3310 case BFD_RELOC_M68HC12_5B
:
3311 if (value
< -16 || value
> 15)
3312 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3313 _("Offset out of 5-bit range for movw/movb insn: %ld"),
3318 where
[0] |= (0x10 | (16 + value
));
3321 case BFD_RELOC_M68HC11_RL_JUMP
:
3322 case BFD_RELOC_M68HC11_RL_GROUP
:
3323 case BFD_RELOC_VTABLE_INHERIT
:
3324 case BFD_RELOC_VTABLE_ENTRY
:
3329 as_fatal (_("Line %d: unknown relocation type: 0x%x."),
3330 fixP
->fx_line
, fixP
->fx_r_type
);
3334 /* Set the ELF specific flags. */
3336 m68hc11_elf_final_processing (void)
3338 if (current_architecture
& cpu6812s
)
3339 elf_flags
|= EF_M68HCS12_MACH
;
3340 elf_elfheader (stdoutput
)->e_flags
&= ~EF_M68HC11_ABI
;
3341 elf_elfheader (stdoutput
)->e_flags
|= elf_flags
;