1 /* tc-m68hc11.c -- Assembler code for the Motorola 68HC11 & 68HC12.
2 Copyright 1999, 2000, 2001, 2002, 2003, 2004 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. */
23 #include "safe-ctype.h"
25 #include "opcode/m68hc11.h"
26 #include "dwarf2dbg.h"
27 #include "elf/m68hc11.h"
29 const char comment_chars
[] = ";!";
30 const char line_comment_chars
[] = "#*";
31 const char line_separator_chars
[] = "";
33 const char EXP_CHARS
[] = "eE";
34 const char FLT_CHARS
[] = "dD";
36 #define STATE_CONDITIONAL_BRANCH (1)
37 #define STATE_PC_RELATIVE (2)
38 #define STATE_INDEXED_OFFSET (3)
39 #define STATE_INDEXED_PCREL (4)
40 #define STATE_XBCC_BRANCH (5)
41 #define STATE_CONDITIONAL_BRANCH_6812 (6)
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 PC relative offset: 5-bits, 9-bits, 16-bits.
94 For the 9-bit case, there will be a -1 correction to take into
95 account the new byte that's why the range is -255..256. */
96 {(15), (-16), 0, ENCODE_RELAX (STATE_INDEXED_PCREL
, STATE_BITS9
)},
97 {(256), (-255), 1, ENCODE_RELAX (STATE_INDEXED_PCREL
, STATE_BITS16
)},
101 /* Relax for dbeq/ibeq/tbeq r,<L>:
102 These insns are translated into db!cc +3 jmp L. */
103 {(255), (-256), 0, ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_WORD
)},
108 /* Relax for bcc <L> on 68HC12.
109 These insns are translated into lbcc <L>. */
110 {(127), (-128), 0, ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
, STATE_WORD
)},
117 /* 68HC11 and 68HC12 registers. They are numbered according to the 68HC12. */
118 typedef enum register_id
{
130 typedef struct operand
{
137 struct m68hc11_opcode_def
{
143 struct m68hc11_opcode
*opcode
;
146 static struct m68hc11_opcode_def
*m68hc11_opcode_defs
= 0;
147 static int m68hc11_nb_opcode_defs
= 0;
149 typedef struct alias
{
154 static alias alias_opcodes
[] = {
161 /* Local functions. */
162 static register_id
reg_name_search (char *);
163 static register_id
register_name (void);
164 static int cmp_opcode (struct m68hc11_opcode
*, struct m68hc11_opcode
*);
165 static char *print_opcode_format (struct m68hc11_opcode
*, int);
166 static char *skip_whites (char *);
167 static int check_range (long, int);
168 static void print_opcode_list (void);
169 static void get_default_target (void);
170 static void print_insn_format (char *);
171 static int get_operand (operand
*, int, long);
172 static void fixup8 (expressionS
*, int, int);
173 static void fixup16 (expressionS
*, int, int);
174 static void fixup24 (expressionS
*, int, int);
175 static unsigned char convert_branch (unsigned char);
176 static char *m68hc11_new_insn (int);
177 static void build_dbranch_insn (struct m68hc11_opcode
*,
178 operand
*, int, int);
179 static int build_indexed_byte (operand
*, int, int);
180 static int build_reg_mode (operand
*, int);
182 static struct m68hc11_opcode
*find (struct m68hc11_opcode_def
*,
184 static struct m68hc11_opcode
*find_opcode (struct m68hc11_opcode_def
*,
186 static void build_jump_insn (struct m68hc11_opcode
*, operand
*, int, int);
187 static void build_insn (struct m68hc11_opcode
*, operand
*, int);
188 static int relaxable_symbol (symbolS
*);
190 /* Pseudo op to indicate a relax group. */
191 static void s_m68hc11_relax (int);
193 /* Pseudo op to control the ELF flags. */
194 static void s_m68hc11_mode (int);
196 /* Mark the symbols with STO_M68HC12_FAR to indicate the functions
197 are using 'rtc' for returning. It is necessary to use 'call'
198 to invoke them. This is also used by the debugger to correctly
199 find the stack frame. */
200 static void s_m68hc11_mark_symbol (int);
202 /* Controls whether relative branches can be turned into long branches.
203 When the relative offset is too large, the insn are changed:
211 Setting the flag forbidds this. */
212 static short flag_fixed_branchs
= 0;
214 /* Force to use long jumps (absolute) instead of relative branches. */
215 static short flag_force_long_jumps
= 0;
217 /* Change the direct addressing mode into an absolute addressing mode
218 when the insn does not support direct addressing.
219 For example, "clr *ZD0" is normally not possible and is changed
221 static short flag_strict_direct_addressing
= 1;
223 /* When an opcode has invalid operand, print out the syntax of the opcode
225 static short flag_print_insn_syntax
= 0;
227 /* Dumps the list of instructions with syntax and then exit:
228 1 -> Only dumps the list (sorted by name)
229 2 -> Generate an example (or test) that can be compiled. */
230 static short flag_print_opcodes
= 0;
232 /* Opcode hash table. */
233 static struct hash_control
*m68hc11_hash
;
235 /* Current cpu (either cpu6811 or cpu6812). This is determined automagically
236 by 'get_default_target' by looking at default BFD vector. This is overridden
237 with the -m<cpu> option. */
238 static int current_architecture
= 0;
240 /* Default cpu determined by 'get_default_target'. */
241 static const char *default_cpu
;
243 /* Number of opcodes in the sorted table (filtered by current cpu). */
244 static int num_opcodes
;
246 /* The opcodes sorted by name and filtered by current cpu. */
247 static struct m68hc11_opcode
*m68hc11_sorted_opcodes
;
249 /* ELF flags to set in the output file header. */
250 static int elf_flags
= E_M68HC11_F64
;
252 /* These are the machine dependent pseudo-ops. These are included so
253 the assembler can work on the output from the SUN C compiler, which
256 /* This table describes all the machine specific pseudo-ops the assembler
257 has to support. The fields are:
258 pseudo-op name without dot
259 function to call to execute this pseudo-op
260 Integer arg to pass to the function. */
261 const pseudo_typeS md_pseudo_table
[] = {
262 /* The following pseudo-ops are supported for MRI compatibility. */
265 {"fcc", stringer
, 1},
269 {"xrefb", s_ignore
, 0}, /* Same as xref */
271 /* Gcc driven relaxation. */
272 {"relax", s_m68hc11_relax
, 0},
274 /* .mode instruction (ala SH). */
275 {"mode", s_m68hc11_mode
, 0},
277 /* .far instruction. */
278 {"far", s_m68hc11_mark_symbol
, STO_M68HC12_FAR
},
280 /* .interrupt instruction. */
281 {"interrupt", s_m68hc11_mark_symbol
, STO_M68HC12_INTERRUPT
},
286 /* Options and initialization. */
288 const char *md_shortopts
= "Sm:";
290 struct option md_longopts
[] = {
291 #define OPTION_FORCE_LONG_BRANCH (OPTION_MD_BASE)
292 {"force-long-branchs", no_argument
, NULL
, OPTION_FORCE_LONG_BRANCH
},
294 #define OPTION_SHORT_BRANCHS (OPTION_MD_BASE + 1)
295 {"short-branchs", no_argument
, NULL
, OPTION_SHORT_BRANCHS
},
297 #define OPTION_STRICT_DIRECT_MODE (OPTION_MD_BASE + 2)
298 {"strict-direct-mode", no_argument
, NULL
, OPTION_STRICT_DIRECT_MODE
},
300 #define OPTION_PRINT_INSN_SYNTAX (OPTION_MD_BASE + 3)
301 {"print-insn-syntax", no_argument
, NULL
, OPTION_PRINT_INSN_SYNTAX
},
303 #define OPTION_PRINT_OPCODES (OPTION_MD_BASE + 4)
304 {"print-opcodes", no_argument
, NULL
, OPTION_PRINT_OPCODES
},
306 #define OPTION_GENERATE_EXAMPLE (OPTION_MD_BASE + 5)
307 {"generate-example", no_argument
, NULL
, OPTION_GENERATE_EXAMPLE
},
309 #define OPTION_MSHORT (OPTION_MD_BASE + 6)
310 {"mshort", no_argument
, NULL
, OPTION_MSHORT
},
312 #define OPTION_MLONG (OPTION_MD_BASE + 7)
313 {"mlong", no_argument
, NULL
, OPTION_MLONG
},
315 #define OPTION_MSHORT_DOUBLE (OPTION_MD_BASE + 8)
316 {"mshort-double", no_argument
, NULL
, OPTION_MSHORT_DOUBLE
},
318 #define OPTION_MLONG_DOUBLE (OPTION_MD_BASE + 9)
319 {"mlong-double", no_argument
, NULL
, OPTION_MLONG_DOUBLE
},
321 {NULL
, no_argument
, NULL
, 0}
323 size_t md_longopts_size
= sizeof (md_longopts
);
325 /* Get the target cpu for the assembler. This is based on the configure
326 options and on the -m68hc11/-m68hc12 option. If no option is specified,
327 we must get the default. */
329 m68hc11_arch_format (void)
331 get_default_target ();
332 if (current_architecture
& cpu6811
)
333 return "elf32-m68hc11";
335 return "elf32-m68hc12";
338 enum bfd_architecture
341 get_default_target ();
342 if (current_architecture
& cpu6811
)
343 return bfd_arch_m68hc11
;
345 return bfd_arch_m68hc12
;
354 /* Listing header selected according to cpu. */
356 m68hc11_listing_header (void)
358 if (current_architecture
& cpu6811
)
359 return "M68HC11 GAS ";
361 return "M68HC12 GAS ";
365 md_show_usage (FILE *stream
)
367 get_default_target ();
368 fprintf (stream
, _("\
369 Motorola 68HC11/68HC12/68HCS12 options:\n\
370 -m68hc11 | -m68hc12 |\n\
371 -m68hcs12 specify the processor [default %s]\n\
372 -mshort use 16-bit int ABI (default)\n\
373 -mlong use 32-bit int ABI\n\
374 -mshort-double use 32-bit double ABI\n\
375 -mlong-double use 64-bit double ABI (default)\n\
376 --force-long-branchs always turn relative branchs into absolute ones\n\
377 -S,--short-branchs do not turn relative branchs into absolute ones\n\
378 when the offset is out of range\n\
379 --strict-direct-mode do not turn the direct mode into extended mode\n\
380 when the instruction does not support direct mode\n\
381 --print-insn-syntax print the syntax of instruction in case of error\n\
382 --print-opcodes print the list of instructions with syntax\n\
383 --generate-example generate an example of each instruction\n\
384 (used for testing)\n"), default_cpu
);
388 /* Try to identify the default target based on the BFD library. */
390 get_default_target (void)
392 const bfd_target
*target
;
395 if (current_architecture
!= 0)
398 default_cpu
= "unknown";
399 target
= bfd_find_target (0, &abfd
);
400 if (target
&& target
->name
)
402 if (strcmp (target
->name
, "elf32-m68hc12") == 0)
404 current_architecture
= cpu6812
;
405 default_cpu
= "m68hc12";
407 else if (strcmp (target
->name
, "elf32-m68hc11") == 0)
409 current_architecture
= cpu6811
;
410 default_cpu
= "m68hc11";
414 as_bad (_("Default target `%s' is not supported."), target
->name
);
420 m68hc11_print_statistics (FILE *file
)
423 struct m68hc11_opcode_def
*opc
;
425 hash_print_statistics (file
, "opcode table", m68hc11_hash
);
427 opc
= m68hc11_opcode_defs
;
428 if (opc
== 0 || m68hc11_nb_opcode_defs
== 0)
431 /* Dump the opcode statistics table. */
432 fprintf (file
, _("Name # Modes Min ops Max ops Modes mask # Used\n"));
433 for (i
= 0; i
< m68hc11_nb_opcode_defs
; i
++, opc
++)
435 fprintf (file
, "%-7.7s %5d %7d %7d 0x%08lx %7d\n",
438 opc
->min_operands
, opc
->max_operands
, opc
->format
, opc
->used
);
443 md_parse_option (int c
, char *arg
)
445 get_default_target ();
448 /* -S means keep external to 2 bit offset rather than 16 bit one. */
449 case OPTION_SHORT_BRANCHS
:
451 flag_fixed_branchs
= 1;
454 case OPTION_FORCE_LONG_BRANCH
:
455 flag_force_long_jumps
= 1;
458 case OPTION_PRINT_INSN_SYNTAX
:
459 flag_print_insn_syntax
= 1;
462 case OPTION_PRINT_OPCODES
:
463 flag_print_opcodes
= 1;
466 case OPTION_STRICT_DIRECT_MODE
:
467 flag_strict_direct_addressing
= 0;
470 case OPTION_GENERATE_EXAMPLE
:
471 flag_print_opcodes
= 2;
475 elf_flags
&= ~E_M68HC11_I32
;
479 elf_flags
|= E_M68HC11_I32
;
482 case OPTION_MSHORT_DOUBLE
:
483 elf_flags
&= ~E_M68HC11_F64
;
486 case OPTION_MLONG_DOUBLE
:
487 elf_flags
|= E_M68HC11_F64
;
491 if (strcasecmp (arg
, "68hc11") == 0)
492 current_architecture
= cpu6811
;
493 else if (strcasecmp (arg
, "68hc12") == 0)
494 current_architecture
= cpu6812
;
495 else if (strcasecmp (arg
, "68hcs12") == 0)
496 current_architecture
= cpu6812
| cpu6812s
;
498 as_bad (_("Option `%s' is not recognized."), arg
);
509 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
514 /* Equal to MAX_PRECISION in atof-ieee.c. */
515 #define MAX_LITTLENUMS 6
517 /* Turn a string in input_line_pointer into a floating point constant
518 of type TYPE, and store the appropriate bytes in *LITP. The number
519 of LITTLENUMS emitted is stored in *SIZEP. An error message is
520 returned, or NULL on OK. */
522 md_atof (int type
, char *litP
, int *sizeP
)
525 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
526 LITTLENUM_TYPE
*wordP
;
557 return _("Bad call to MD_ATOF()");
559 t
= atof_ieee (input_line_pointer
, type
, words
);
561 input_line_pointer
= t
;
563 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
564 for (wordP
= words
; prec
--;)
566 md_number_to_chars (litP
, (long) (*wordP
++), sizeof (LITTLENUM_TYPE
));
567 litP
+= sizeof (LITTLENUM_TYPE
);
573 md_section_align (asection
*seg
, valueT addr
)
575 int align
= bfd_get_section_alignment (stdoutput
, seg
);
576 return ((addr
+ (1 << align
) - 1) & (-1 << align
));
580 cmp_opcode (struct m68hc11_opcode
*op1
, struct m68hc11_opcode
*op2
)
582 return strcmp (op1
->name
, op2
->name
);
585 #define IS_CALL_SYMBOL(MODE) \
586 (((MODE) & (M6812_OP_PAGE|M6811_OP_IND16)) \
587 == ((M6812_OP_PAGE|M6811_OP_IND16)))
589 /* Initialize the assembler. Create the opcode hash table
590 (sorted on the names) with the M6811 opcode table
591 (from opcode library). */
595 char *prev_name
= "";
596 struct m68hc11_opcode
*opcodes
;
597 struct m68hc11_opcode_def
*opc
= 0;
600 get_default_target ();
602 m68hc11_hash
= hash_new ();
604 /* Get a writable copy of the opcode table and sort it on the names. */
605 opcodes
= (struct m68hc11_opcode
*) xmalloc (m68hc11_num_opcodes
*
608 m68hc11_sorted_opcodes
= opcodes
;
610 for (i
= 0; i
< m68hc11_num_opcodes
; i
++)
612 if (m68hc11_opcodes
[i
].arch
& current_architecture
)
614 opcodes
[num_opcodes
] = m68hc11_opcodes
[i
];
615 if (opcodes
[num_opcodes
].name
[0] == 'b'
616 && opcodes
[num_opcodes
].format
& M6811_OP_JUMP_REL
617 && !(opcodes
[num_opcodes
].format
& M6811_OP_BITMASK
))
620 opcodes
[num_opcodes
] = m68hc11_opcodes
[i
];
623 for (j
= 0; alias_opcodes
[j
].name
!= 0; j
++)
624 if (strcmp (m68hc11_opcodes
[i
].name
, alias_opcodes
[j
].name
) == 0)
626 opcodes
[num_opcodes
] = m68hc11_opcodes
[i
];
627 opcodes
[num_opcodes
].name
= alias_opcodes
[j
].alias
;
633 qsort (opcodes
, num_opcodes
, sizeof (struct m68hc11_opcode
),
634 (int (*) (const void*, const void*)) cmp_opcode
);
636 opc
= (struct m68hc11_opcode_def
*)
637 xmalloc (num_opcodes
* sizeof (struct m68hc11_opcode_def
));
638 m68hc11_opcode_defs
= opc
--;
640 /* Insert unique names into hash table. The M6811 instruction set
641 has several identical opcode names that have different opcodes based
642 on the operands. This hash table then provides a quick index to
643 the first opcode with a particular name in the opcode table. */
644 for (i
= 0; i
< num_opcodes
; i
++, opcodes
++)
648 if (strcmp (prev_name
, opcodes
->name
))
650 prev_name
= (char *) opcodes
->name
;
654 opc
->min_operands
= 100;
655 opc
->max_operands
= 0;
657 opc
->opcode
= opcodes
;
659 hash_insert (m68hc11_hash
, opcodes
->name
, opc
);
662 opc
->format
|= opcodes
->format
;
664 /* See how many operands this opcode needs. */
666 if (opcodes
->format
& M6811_OP_MASK
)
668 if (opcodes
->format
& M6811_OP_BITMASK
)
670 if (opcodes
->format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
672 if (opcodes
->format
& (M6812_OP_IND16_P2
| M6812_OP_IDX_P2
))
674 /* Special case for call instruction. */
675 if ((opcodes
->format
& M6812_OP_PAGE
)
676 && !(opcodes
->format
& M6811_OP_IND16
))
679 if (expect
< opc
->min_operands
)
680 opc
->min_operands
= expect
;
681 if (IS_CALL_SYMBOL (opcodes
->format
))
683 if (expect
> opc
->max_operands
)
684 opc
->max_operands
= expect
;
687 m68hc11_nb_opcode_defs
= opc
- m68hc11_opcode_defs
;
689 if (flag_print_opcodes
)
691 print_opcode_list ();
697 m68hc11_init_after_args (void)
703 /* Return a string that represents the operand format for the instruction.
704 When example is true, this generates an example of operand. This is used
705 to give an example and also to generate a test. */
707 print_opcode_format (struct m68hc11_opcode
*opcode
, int example
)
709 static char buf
[128];
710 int format
= opcode
->format
;
715 if (format
& M6811_OP_IMM8
)
718 sprintf (p
, "#%d", rand () & 0x0FF);
720 strcpy (p
, _("#<imm8>"));
724 if (format
& M6811_OP_IMM16
)
727 sprintf (p
, "#%d", rand () & 0x0FFFF);
729 strcpy (p
, _("#<imm16>"));
733 if (format
& M6811_OP_IX
)
736 sprintf (p
, "%d,X", rand () & 0x0FF);
738 strcpy (p
, _("<imm8>,X"));
742 if (format
& M6811_OP_IY
)
745 sprintf (p
, "%d,X", rand () & 0x0FF);
747 strcpy (p
, _("<imm8>,X"));
751 if (format
& M6812_OP_IDX
)
754 sprintf (p
, "%d,X", rand () & 0x0FF);
760 if (format
& M6812_OP_PAGE
)
763 sprintf (p
, ", %d", rand () & 0x0FF);
765 strcpy (p
, ", <page>");
769 if (format
& M6811_OP_DIRECT
)
772 sprintf (p
, "*Z%d", rand () & 0x0FF);
774 strcpy (p
, _("*<abs8>"));
778 if (format
& M6811_OP_BITMASK
)
784 sprintf (p
, "#$%02x", rand () & 0x0FF);
786 strcpy (p
, _("#<mask>"));
789 if (format
& M6811_OP_JUMP_REL
)
793 if (format
& M6811_OP_IND16
)
796 sprintf (p
, _("symbol%d"), rand () & 0x0FF);
798 strcpy (p
, _("<abs>"));
803 if (format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
807 if (format
& M6811_OP_BITMASK
)
809 sprintf (p
, ".+%d", rand () & 0x7F);
813 sprintf (p
, "L%d", rand () & 0x0FF);
817 strcpy (p
, _("<label>"));
823 /* Prints the list of instructions with the possible operands. */
825 print_opcode_list (void)
828 char *prev_name
= "";
829 struct m68hc11_opcode
*opcodes
;
830 int example
= flag_print_opcodes
== 2;
833 printf (_("# Example of `%s' instructions\n\t.sect .text\n_start:\n"),
836 opcodes
= m68hc11_sorted_opcodes
;
838 /* Walk the list sorted on names (by md_begin). We only report
839 one instruction per line, and we collect the different operand
841 for (i
= 0; i
< num_opcodes
; i
++, opcodes
++)
843 char *fmt
= print_opcode_format (opcodes
, example
);
847 printf ("L%d:\t", i
);
848 printf ("%s %s\n", opcodes
->name
, fmt
);
852 if (strcmp (prev_name
, opcodes
->name
))
857 printf ("%-5.5s ", opcodes
->name
);
858 prev_name
= (char *) opcodes
->name
;
861 printf (" [%s]", fmt
);
867 /* Print the instruction format. This operation is called when some
868 instruction is not correct. Instruction format is printed as an
871 print_insn_format (char *name
)
873 struct m68hc11_opcode_def
*opc
;
874 struct m68hc11_opcode
*opcode
;
877 opc
= (struct m68hc11_opcode_def
*) hash_find (m68hc11_hash
, name
);
880 as_bad (_("Instruction `%s' is not recognized."), name
);
883 opcode
= opc
->opcode
;
885 as_bad (_("Instruction formats for `%s':"), name
);
890 fmt
= print_opcode_format (opcode
, 0);
891 sprintf (buf
, "\t%-5.5s %s", opcode
->name
, fmt
);
896 while (strcmp (opcode
->name
, name
) == 0);
899 /* Analysis of 68HC11 and 68HC12 operands. */
901 /* reg_name_search() finds the register number given its name.
902 Returns the register number or REG_NONE on failure. */
904 reg_name_search (char *name
)
906 if (strcasecmp (name
, "x") == 0 || strcasecmp (name
, "ix") == 0)
908 if (strcasecmp (name
, "y") == 0 || strcasecmp (name
, "iy") == 0)
910 if (strcasecmp (name
, "a") == 0)
912 if (strcasecmp (name
, "b") == 0)
914 if (strcasecmp (name
, "d") == 0)
916 if (strcasecmp (name
, "sp") == 0)
918 if (strcasecmp (name
, "pc") == 0)
920 if (strcasecmp (name
, "ccr") == 0)
927 skip_whites (char *p
)
929 while (*p
== ' ' || *p
== '\t')
935 /* Check the string at input_line_pointer
936 to see if it is a valid register name. */
940 register_id reg_number
;
941 char c
, *p
= input_line_pointer
;
943 if (!is_name_beginner (*p
++))
946 while (is_part_of_name (*p
++))
953 /* Look to see if it's in the register table. */
954 reg_number
= reg_name_search (input_line_pointer
);
955 if (reg_number
!= REG_NONE
)
960 input_line_pointer
= p
;
968 #define M6811_OP_CALL_ADDR 0x00800000
969 #define M6811_OP_PAGE_ADDR 0x04000000
971 /* Parse a string of operands and return an array of expressions.
973 Operand mode[0] mode[1] exp[0] exp[1]
974 #n M6811_OP_IMM16 - O_*
975 *<exp> M6811_OP_DIRECT - O_*
976 .{+-}<exp> M6811_OP_JUMP_REL - O_*
977 <exp> M6811_OP_IND16 - O_*
978 ,r N,r M6812_OP_IDX M6812_OP_REG O_constant O_register
979 n,-r M6812_PRE_DEC M6812_OP_REG O_constant O_register
980 n,+r M6812_PRE_INC " "
981 n,r- M6812_POST_DEC " "
982 n,r+ M6812_POST_INC " "
983 A,r B,r D,r M6811_OP_REG M6812_OP_REG O_register O_register
984 [D,r] M6811_OP_D_IDX M6812_OP_REG O_register O_register
985 [n,r] M6811_OP_D_IDX_2 M6812_OP_REG O_constant O_register */
987 get_operand (operand
*oper
, int which
, long opmode
)
989 char *p
= input_line_pointer
;
993 oper
->exp
.X_op
= O_absent
;
994 oper
->reg1
= REG_NONE
;
995 oper
->reg2
= REG_NONE
;
996 mode
= M6811_OP_NONE
;
1000 if (*p
== 0 || *p
== '\n' || *p
== '\r')
1002 input_line_pointer
= p
;
1006 if (*p
== '*' && (opmode
& (M6811_OP_DIRECT
| M6811_OP_IND16
)))
1008 mode
= M6811_OP_DIRECT
;
1013 if (!(opmode
& (M6811_OP_IMM8
| M6811_OP_IMM16
| M6811_OP_BITMASK
)))
1015 as_bad (_("Immediate operand is not allowed for operand %d."),
1020 mode
= M6811_OP_IMM16
;
1022 if (strncmp (p
, "%hi", 3) == 0)
1025 mode
|= M6811_OP_HIGH_ADDR
;
1027 else if (strncmp (p
, "%lo", 3) == 0)
1030 mode
|= M6811_OP_LOW_ADDR
;
1032 /* %page modifier is used to obtain only the page number
1033 of the address of a function. */
1034 else if (strncmp (p
, "%page", 5) == 0)
1037 mode
|= M6811_OP_PAGE_ADDR
;
1040 /* %addr modifier is used to obtain the physical address part
1041 of the function (16-bit). For 68HC12 the function will be
1042 mapped in the 16K window at 0x8000 and the value will be
1043 within that window (although the function address may not fit
1044 in 16-bit). See bfd/elf32-m68hc12.c for the translation. */
1045 else if (strncmp (p
, "%addr", 5) == 0)
1048 mode
|= M6811_OP_CALL_ADDR
;
1051 else if (*p
== '.' && (p
[1] == '+' || p
[1] == '-'))
1054 mode
= M6811_OP_JUMP_REL
;
1058 if (current_architecture
& cpu6811
)
1059 as_bad (_("Indirect indexed addressing is not valid for 68HC11."));
1062 mode
= M6812_OP_D_IDX
;
1063 p
= skip_whites (p
);
1065 else if (*p
== ',') /* Special handling of ,x and ,y. */
1068 input_line_pointer
= p
;
1070 reg
= register_name ();
1071 if (reg
!= REG_NONE
)
1074 oper
->exp
.X_op
= O_constant
;
1075 oper
->exp
.X_add_number
= 0;
1076 oper
->mode
= M6812_OP_IDX
;
1079 as_bad (_("Spurious `,' or bad indirect register addressing mode."));
1082 /* Handle 68HC12 page specification in 'call foo,%page(bar)'. */
1083 else if ((opmode
& M6812_OP_PAGE
) && strncmp (p
, "%page", 5) == 0)
1086 mode
= M6811_OP_PAGE_ADDR
| M6812_OP_PAGE
| M6811_OP_IND16
;
1088 input_line_pointer
= p
;
1090 if (mode
== M6811_OP_NONE
|| mode
== M6812_OP_D_IDX
)
1091 reg
= register_name ();
1095 if (reg
!= REG_NONE
)
1097 p
= skip_whites (input_line_pointer
);
1098 if (*p
== ']' && mode
== M6812_OP_D_IDX
)
1101 (_("Missing second register or offset for indexed-indirect mode."));
1106 oper
->mode
= mode
| M6812_OP_REG
;
1109 if (mode
== M6812_OP_D_IDX
)
1111 as_bad (_("Missing second register for indexed-indirect mode."));
1118 input_line_pointer
= p
;
1119 reg
= register_name ();
1120 if (reg
!= REG_NONE
)
1122 p
= skip_whites (input_line_pointer
);
1123 if (mode
== M6812_OP_D_IDX
)
1127 as_bad (_("Missing `]' to close indexed-indirect mode."));
1131 oper
->mode
= M6812_OP_D_IDX
;
1133 input_line_pointer
= p
;
1141 /* In MRI mode, isolate the operand because we can't distinguish
1142 operands from comments. */
1147 p
= skip_whites (p
);
1148 while (*p
&& *p
!= ' ' && *p
!= '\t')
1157 /* Parse as an expression. */
1158 expression (&oper
->exp
);
1167 expression (&oper
->exp
);
1170 if (oper
->exp
.X_op
== O_illegal
)
1172 as_bad (_("Illegal operand."));
1175 else if (oper
->exp
.X_op
== O_absent
)
1177 as_bad (_("Missing operand."));
1181 p
= input_line_pointer
;
1183 if (mode
== M6811_OP_NONE
|| mode
== M6811_OP_DIRECT
1184 || mode
== M6812_OP_D_IDX
)
1186 p
= skip_whites (input_line_pointer
);
1190 int possible_mode
= M6811_OP_NONE
;
1191 char *old_input_line
;
1196 /* 68HC12 pre increment or decrement. */
1197 if (mode
== M6811_OP_NONE
)
1201 possible_mode
= M6812_PRE_DEC
;
1206 possible_mode
= M6812_PRE_INC
;
1209 p
= skip_whites (p
);
1211 input_line_pointer
= p
;
1212 reg
= register_name ();
1214 /* Backtrack if we have a valid constant expression and
1215 it does not correspond to the offset of the 68HC12 indexed
1216 addressing mode (as in N,x). */
1217 if (reg
== REG_NONE
&& mode
== M6811_OP_NONE
1218 && possible_mode
!= M6811_OP_NONE
)
1220 oper
->mode
= M6811_OP_IND16
| M6811_OP_JUMP_REL
;
1221 input_line_pointer
= skip_whites (old_input_line
);
1225 if (possible_mode
!= M6811_OP_NONE
)
1226 mode
= possible_mode
;
1228 if ((current_architecture
& cpu6811
)
1229 && possible_mode
!= M6811_OP_NONE
)
1230 as_bad (_("Pre-increment mode is not valid for 68HC11"));
1232 if (which
== 0 && opmode
& M6812_OP_IDX_P2
1233 && reg
!= REG_X
&& reg
!= REG_Y
1234 && reg
!= REG_PC
&& reg
!= REG_SP
)
1237 input_line_pointer
= p
;
1240 if (reg
== REG_NONE
&& mode
!= M6811_OP_DIRECT
1241 && !(mode
== M6811_OP_NONE
&& opmode
& M6811_OP_IND16
))
1243 as_bad (_("Wrong register in register indirect mode."));
1246 if (mode
== M6812_OP_D_IDX
)
1248 p
= skip_whites (input_line_pointer
);
1251 as_bad (_("Missing `]' to close register indirect operand."));
1254 input_line_pointer
= p
;
1256 oper
->mode
= M6812_OP_D_IDX_2
;
1259 if (reg
!= REG_NONE
)
1262 if (mode
== M6811_OP_NONE
)
1264 p
= input_line_pointer
;
1267 mode
= M6812_POST_DEC
;
1269 if (current_architecture
& cpu6811
)
1271 (_("Post-decrement mode is not valid for 68HC11."));
1275 mode
= M6812_POST_INC
;
1277 if (current_architecture
& cpu6811
)
1279 (_("Post-increment mode is not valid for 68HC11."));
1282 mode
= M6812_OP_IDX
;
1284 input_line_pointer
= p
;
1287 mode
|= M6812_OP_IDX
;
1292 input_line_pointer
= old_input_line
;
1295 if (mode
== M6812_OP_D_IDX_2
)
1297 as_bad (_("Invalid indexed indirect mode."));
1302 /* If the mode is not known until now, this is either a label
1303 or an indirect address. */
1304 if (mode
== M6811_OP_NONE
)
1305 mode
= M6811_OP_IND16
| M6811_OP_JUMP_REL
;
1307 p
= input_line_pointer
;
1308 while (*p
== ' ' || *p
== '\t')
1310 input_line_pointer
= p
;
1316 #define M6812_AUTO_INC_DEC (M6812_PRE_INC | M6812_PRE_DEC \
1317 | M6812_POST_INC | M6812_POST_DEC)
1319 /* Checks that the number 'num' fits for a given mode. */
1321 check_range (long num
, int mode
)
1323 /* Auto increment and decrement are ok for [-8..8] without 0. */
1324 if (mode
& M6812_AUTO_INC_DEC
)
1325 return (num
!= 0 && num
<= 8 && num
>= -8);
1327 /* The 68HC12 supports 5, 9 and 16-bit offsets. */
1328 if (mode
& (M6812_INDEXED_IND
| M6812_INDEXED
| M6812_OP_IDX
))
1329 mode
= M6811_OP_IND16
;
1331 if (mode
& M6812_OP_JUMP_REL16
)
1332 mode
= M6811_OP_IND16
;
1334 mode
&= ~M6811_OP_BRANCH
;
1339 case M6811_OP_DIRECT
:
1340 return (num
>= 0 && num
<= 255) ? 1 : 0;
1342 case M6811_OP_BITMASK
:
1345 return (((num
& 0xFFFFFF00) == 0) || ((num
& 0xFFFFFF00) == 0xFFFFFF00))
1348 case M6811_OP_JUMP_REL
:
1349 return (num
>= -128 && num
<= 127) ? 1 : 0;
1351 case M6811_OP_IND16
:
1352 case M6811_OP_IND16
| M6812_OP_PAGE
:
1353 case M6811_OP_IMM16
:
1354 return (((num
& 0xFFFF0000) == 0) || ((num
& 0xFFFF0000) == 0xFFFF0000))
1357 case M6812_OP_IBCC_MARKER
:
1358 case M6812_OP_TBCC_MARKER
:
1359 case M6812_OP_DBCC_MARKER
:
1360 return (num
>= -256 && num
<= 255) ? 1 : 0;
1362 case M6812_OP_TRAP_ID
:
1363 return ((num
>= 0x30 && num
<= 0x39)
1364 || (num
>= 0x40 && num
<= 0x0ff)) ? 1 : 0;
1371 /* Gas fixup generation. */
1373 /* Put a 1 byte expression described by 'oper'. If this expression contains
1374 unresolved symbols, generate an 8-bit fixup. */
1376 fixup8 (expressionS
*oper
, int mode
, int opmode
)
1382 if (oper
->X_op
== O_constant
)
1384 if (mode
& M6812_OP_TRAP_ID
1385 && !check_range (oper
->X_add_number
, M6812_OP_TRAP_ID
))
1387 static char trap_id_warn_once
= 0;
1389 as_bad (_("Trap id `%ld' is out of range."), oper
->X_add_number
);
1390 if (trap_id_warn_once
== 0)
1392 trap_id_warn_once
= 1;
1393 as_bad (_("Trap id must be within [0x30..0x39] or [0x40..0xff]."));
1397 if (!(mode
& M6812_OP_TRAP_ID
)
1398 && !check_range (oper
->X_add_number
, mode
))
1400 as_bad (_("Operand out of 8-bit range: `%ld'."), oper
->X_add_number
);
1402 number_to_chars_bigendian (f
, oper
->X_add_number
& 0x0FF, 1);
1404 else if (oper
->X_op
!= O_register
)
1406 if (mode
& M6812_OP_TRAP_ID
)
1407 as_bad (_("The trap id must be a constant."));
1409 if (mode
== M6811_OP_JUMP_REL
)
1413 fixp
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 1,
1414 oper
, TRUE
, BFD_RELOC_8_PCREL
);
1415 fixp
->fx_pcrel_adjust
= 1;
1422 /* Now create an 8-bit fixup. If there was some %hi, %lo
1423 or %page modifier, generate the reloc accordingly. */
1424 if (opmode
& M6811_OP_HIGH_ADDR
)
1425 reloc
= BFD_RELOC_M68HC11_HI8
;
1426 else if (opmode
& M6811_OP_LOW_ADDR
)
1427 reloc
= BFD_RELOC_M68HC11_LO8
;
1428 else if (opmode
& M6811_OP_PAGE_ADDR
)
1429 reloc
= BFD_RELOC_M68HC11_PAGE
;
1431 reloc
= BFD_RELOC_8
;
1433 fixp
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 1,
1434 oper
, FALSE
, reloc
);
1435 if (reloc
!= BFD_RELOC_8
)
1436 fixp
->fx_no_overflow
= 1;
1438 number_to_chars_bigendian (f
, 0, 1);
1442 as_fatal (_("Operand `%x' not recognized in fixup8."), oper
->X_op
);
1446 /* Put a 2 byte expression described by 'oper'. If this expression contains
1447 unresolved symbols, generate a 16-bit fixup. */
1449 fixup16 (expressionS
*oper
, int mode
, int opmode ATTRIBUTE_UNUSED
)
1455 if (oper
->X_op
== O_constant
)
1457 if (!check_range (oper
->X_add_number
, mode
))
1459 as_bad (_("Operand out of 16-bit range: `%ld'."),
1460 oper
->X_add_number
);
1462 number_to_chars_bigendian (f
, oper
->X_add_number
& 0x0FFFF, 2);
1464 else if (oper
->X_op
!= O_register
)
1469 if ((opmode
& M6811_OP_CALL_ADDR
) && (mode
& M6811_OP_IMM16
))
1470 reloc
= BFD_RELOC_M68HC11_LO16
;
1471 else if (mode
& M6812_OP_JUMP_REL16
)
1472 reloc
= BFD_RELOC_16_PCREL
;
1473 else if (mode
& M6812_OP_PAGE
)
1474 reloc
= BFD_RELOC_M68HC11_LO16
;
1476 reloc
= BFD_RELOC_16
;
1478 /* Now create a 16-bit fixup. */
1479 fixp
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 2,
1481 reloc
== BFD_RELOC_16_PCREL
,
1483 number_to_chars_bigendian (f
, 0, 2);
1484 if (reloc
== BFD_RELOC_16_PCREL
)
1485 fixp
->fx_pcrel_adjust
= 2;
1486 if (reloc
== BFD_RELOC_M68HC11_LO16
)
1487 fixp
->fx_no_overflow
= 1;
1491 as_fatal (_("Operand `%x' not recognized in fixup16."), oper
->X_op
);
1495 /* Put a 3 byte expression described by 'oper'. If this expression contains
1496 unresolved symbols, generate a 24-bit fixup. */
1498 fixup24 (expressionS
*oper
, int mode
, int opmode ATTRIBUTE_UNUSED
)
1504 if (oper
->X_op
== O_constant
)
1506 if (!check_range (oper
->X_add_number
, mode
))
1508 as_bad (_("Operand out of 16-bit range: `%ld'."),
1509 oper
->X_add_number
);
1511 number_to_chars_bigendian (f
, oper
->X_add_number
& 0x0FFFFFF, 3);
1513 else if (oper
->X_op
!= O_register
)
1517 /* Now create a 24-bit fixup. */
1518 fixp
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 2,
1519 oper
, FALSE
, BFD_RELOC_M68HC11_24
);
1520 number_to_chars_bigendian (f
, 0, 3);
1524 as_fatal (_("Operand `%x' not recognized in fixup16."), oper
->X_op
);
1528 /* 68HC11 and 68HC12 code generation. */
1530 /* Translate the short branch/bsr instruction into a long branch. */
1531 static unsigned char
1532 convert_branch (unsigned char code
)
1534 if (IS_OPCODE (code
, M6812_BSR
))
1536 else if (IS_OPCODE (code
, M6811_BSR
))
1538 else if (IS_OPCODE (code
, M6811_BRA
))
1539 return (current_architecture
& cpu6812
) ? M6812_JMP
: M6811_JMP
;
1541 as_fatal (_("Unexpected branch conversion with `%x'"), code
);
1543 /* Keep gcc happy. */
1547 /* Start a new insn that contains at least 'size' bytes. Record the
1548 line information of that insn in the dwarf2 debug sections. */
1550 m68hc11_new_insn (int size
)
1554 f
= frag_more (size
);
1556 dwarf2_emit_insn (size
);
1561 /* Builds a jump instruction (bra, bcc, bsr). */
1563 build_jump_insn (struct m68hc11_opcode
*opcode
, operand operands
[],
1564 int nb_operands
, int jmp_mode
)
1572 /* The relative branch conversion is not supported for
1574 assert ((opcode
->format
& M6811_OP_BITMASK
) == 0);
1575 assert (nb_operands
== 1);
1576 assert (operands
[0].reg1
== REG_NONE
&& operands
[0].reg2
== REG_NONE
);
1578 code
= opcode
->opcode
;
1580 n
= operands
[0].exp
.X_add_number
;
1582 /* Turn into a long branch:
1583 - when force long branch option (and not for jbcc pseudos),
1584 - when jbcc and the constant is out of -128..127 range,
1585 - when branch optimization is allowed and branch out of range. */
1586 if ((jmp_mode
== 0 && flag_force_long_jumps
)
1587 || (operands
[0].exp
.X_op
== O_constant
1588 && (!check_range (n
, opcode
->format
) &&
1589 (jmp_mode
== 1 || flag_fixed_branchs
== 0))))
1592 where
= frag_now_fix ();
1594 fix_new (frag_now
, frag_now_fix (), 1,
1595 &abs_symbol
, 0, 1, BFD_RELOC_M68HC11_RL_JUMP
);
1597 if (code
== M6811_BSR
|| code
== M6811_BRA
|| code
== M6812_BSR
)
1599 code
= convert_branch (code
);
1601 f
= m68hc11_new_insn (1);
1602 number_to_chars_bigendian (f
, code
, 1);
1604 else if (current_architecture
& cpu6812
)
1606 /* 68HC12: translate the bcc into a lbcc. */
1607 f
= m68hc11_new_insn (2);
1608 number_to_chars_bigendian (f
, M6811_OPCODE_PAGE2
, 1);
1609 number_to_chars_bigendian (f
+ 1, code
, 1);
1610 fixup16 (&operands
[0].exp
, M6812_OP_JUMP_REL16
,
1611 M6812_OP_JUMP_REL16
);
1616 /* 68HC11: translate the bcc into b!cc +3; jmp <L>. */
1617 f
= m68hc11_new_insn (3);
1619 number_to_chars_bigendian (f
, code
, 1);
1620 number_to_chars_bigendian (f
+ 1, 3, 1);
1621 number_to_chars_bigendian (f
+ 2, M6811_JMP
, 1);
1623 fixup16 (&operands
[0].exp
, M6811_OP_IND16
, M6811_OP_IND16
);
1627 /* Branch with a constant that must fit in 8-bits. */
1628 if (operands
[0].exp
.X_op
== O_constant
)
1630 if (!check_range (n
, opcode
->format
))
1632 as_bad (_("Operand out of range for a relative branch: `%ld'"),
1635 else if (opcode
->format
& M6812_OP_JUMP_REL16
)
1637 f
= m68hc11_new_insn (4);
1638 number_to_chars_bigendian (f
, M6811_OPCODE_PAGE2
, 1);
1639 number_to_chars_bigendian (f
+ 1, code
, 1);
1640 number_to_chars_bigendian (f
+ 2, n
& 0x0ffff, 2);
1644 f
= m68hc11_new_insn (2);
1645 number_to_chars_bigendian (f
, code
, 1);
1646 number_to_chars_bigendian (f
+ 1, n
& 0x0FF, 1);
1649 else if (opcode
->format
& M6812_OP_JUMP_REL16
)
1652 where
= frag_now_fix ();
1654 fix_new (frag_now
, frag_now_fix (), 1,
1655 &abs_symbol
, 0, 1, BFD_RELOC_M68HC11_RL_JUMP
);
1657 f
= m68hc11_new_insn (2);
1658 number_to_chars_bigendian (f
, M6811_OPCODE_PAGE2
, 1);
1659 number_to_chars_bigendian (f
+ 1, code
, 1);
1660 fixup16 (&operands
[0].exp
, M6812_OP_JUMP_REL16
, M6812_OP_JUMP_REL16
);
1667 where
= frag_now_fix ();
1669 fix_new (frag_now
, frag_now_fix (), 1,
1670 &abs_symbol
, 0, 1, BFD_RELOC_M68HC11_RL_JUMP
);
1672 /* Branch offset must fit in 8-bits, don't do some relax. */
1673 if (jmp_mode
== 0 && flag_fixed_branchs
)
1675 opcode
= m68hc11_new_insn (1);
1676 number_to_chars_bigendian (opcode
, code
, 1);
1677 fixup8 (&operands
[0].exp
, M6811_OP_JUMP_REL
, M6811_OP_JUMP_REL
);
1680 /* bra/bsr made be changed into jmp/jsr. */
1681 else if (code
== M6811_BSR
|| code
== M6811_BRA
|| code
== M6812_BSR
)
1683 /* Allocate worst case storage. */
1684 opcode
= m68hc11_new_insn (3);
1685 number_to_chars_bigendian (opcode
, code
, 1);
1686 number_to_chars_bigendian (opcode
+ 1, 0, 1);
1687 frag_variant (rs_machine_dependent
, 1, 1,
1688 ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_UNDF
),
1689 operands
[0].exp
.X_add_symbol
, (offsetT
) n
,
1692 else if (current_architecture
& cpu6812
)
1694 opcode
= m68hc11_new_insn (2);
1695 number_to_chars_bigendian (opcode
, code
, 1);
1696 number_to_chars_bigendian (opcode
+ 1, 0, 1);
1697 frag_var (rs_machine_dependent
, 2, 2,
1698 ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
, STATE_UNDF
),
1699 operands
[0].exp
.X_add_symbol
, (offsetT
) n
, opcode
);
1703 opcode
= m68hc11_new_insn (2);
1704 number_to_chars_bigendian (opcode
, code
, 1);
1705 number_to_chars_bigendian (opcode
+ 1, 0, 1);
1706 frag_var (rs_machine_dependent
, 3, 3,
1707 ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
, STATE_UNDF
),
1708 operands
[0].exp
.X_add_symbol
, (offsetT
) n
, opcode
);
1713 /* Builds a dbne/dbeq/tbne/tbeq instruction. */
1715 build_dbranch_insn (struct m68hc11_opcode
*opcode
, operand operands
[],
1716 int nb_operands
, int jmp_mode
)
1722 /* The relative branch conversion is not supported for
1724 assert ((opcode
->format
& M6811_OP_BITMASK
) == 0);
1725 assert (nb_operands
== 2);
1726 assert (operands
[0].reg1
!= REG_NONE
);
1728 code
= opcode
->opcode
& 0x0FF;
1730 f
= m68hc11_new_insn (1);
1731 number_to_chars_bigendian (f
, code
, 1);
1733 n
= operands
[1].exp
.X_add_number
;
1734 code
= operands
[0].reg1
;
1736 if (operands
[0].reg1
== REG_NONE
|| operands
[0].reg1
== REG_CCR
1737 || operands
[0].reg1
== REG_PC
)
1738 as_bad (_("Invalid register for dbcc/tbcc instruction."));
1740 if (opcode
->format
& M6812_OP_IBCC_MARKER
)
1742 else if (opcode
->format
& M6812_OP_TBCC_MARKER
)
1745 if (!(opcode
->format
& M6812_OP_EQ_MARKER
))
1748 /* Turn into a long branch:
1749 - when force long branch option (and not for jbcc pseudos),
1750 - when jdbcc and the constant is out of -256..255 range,
1751 - when branch optimization is allowed and branch out of range. */
1752 if ((jmp_mode
== 0 && flag_force_long_jumps
)
1753 || (operands
[1].exp
.X_op
== O_constant
1754 && (!check_range (n
, M6812_OP_IBCC_MARKER
) &&
1755 (jmp_mode
== 1 || flag_fixed_branchs
== 0))))
1759 number_to_chars_bigendian (f
, code
, 1);
1760 number_to_chars_bigendian (f
+ 1, M6812_JMP
, 1);
1761 fixup16 (&operands
[0].exp
, M6811_OP_IND16
, M6811_OP_IND16
);
1765 /* Branch with a constant that must fit in 9-bits. */
1766 if (operands
[1].exp
.X_op
== O_constant
)
1768 if (!check_range (n
, M6812_OP_IBCC_MARKER
))
1770 as_bad (_("Operand out of range for a relative branch: `%ld'"),
1779 number_to_chars_bigendian (f
, code
, 1);
1780 number_to_chars_bigendian (f
+ 1, n
& 0x0FF, 1);
1785 /* Branch offset must fit in 8-bits, don't do some relax. */
1786 if (jmp_mode
== 0 && flag_fixed_branchs
)
1788 fixup8 (&operands
[0].exp
, M6811_OP_JUMP_REL
, M6811_OP_JUMP_REL
);
1794 number_to_chars_bigendian (f
, code
, 1);
1795 number_to_chars_bigendian (f
+ 1, 0, 1);
1796 frag_var (rs_machine_dependent
, 3, 3,
1797 ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_UNDF
),
1798 operands
[1].exp
.X_add_symbol
, (offsetT
) n
, f
);
1803 #define OP_EXTENDED (M6811_OP_PAGE2 | M6811_OP_PAGE3 | M6811_OP_PAGE4)
1805 /* Assemble the post index byte for 68HC12 extended addressing modes. */
1807 build_indexed_byte (operand
*op
, int format ATTRIBUTE_UNUSED
, int move_insn
)
1809 unsigned char byte
= 0;
1814 val
= op
->exp
.X_add_number
;
1816 if (mode
& M6812_AUTO_INC_DEC
)
1819 if (mode
& (M6812_POST_INC
| M6812_POST_DEC
))
1822 if (op
->exp
.X_op
== O_constant
)
1824 if (!check_range (val
, mode
))
1826 as_bad (_("Increment/decrement value is out of range: `%ld'."),
1829 if (mode
& (M6812_POST_INC
| M6812_PRE_INC
))
1830 byte
|= (val
- 1) & 0x07;
1832 byte
|= (8 - ((val
) & 7)) | 0x8;
1837 as_fatal (_("Expecting a register."));
1852 as_bad (_("Invalid register for post/pre increment."));
1857 number_to_chars_bigendian (f
, byte
, 1);
1861 if (mode
& (M6812_OP_IDX
| M6812_OP_D_IDX_2
))
1882 as_bad (_("Invalid register."));
1885 if (op
->exp
.X_op
== O_constant
)
1887 if (!check_range (val
, M6812_OP_IDX
))
1889 as_bad (_("Offset out of 16-bit range: %ld."), val
);
1892 if (move_insn
&& !(val
>= -16 && val
<= 15))
1894 as_bad (_("Offset out of 5-bit range for movw/movb insn: %ld."),
1899 if (val
>= -16 && val
<= 15 && !(mode
& M6812_OP_D_IDX_2
))
1904 number_to_chars_bigendian (f
, byte
, 1);
1907 else if (val
>= -256 && val
<= 255 && !(mode
& M6812_OP_D_IDX_2
))
1914 number_to_chars_bigendian (f
, byte
, 1);
1915 number_to_chars_bigendian (f
+ 1, val
& 0x0FF, 1);
1921 if (mode
& M6812_OP_D_IDX_2
)
1927 number_to_chars_bigendian (f
, byte
, 1);
1928 number_to_chars_bigendian (f
+ 1, val
& 0x0FFFF, 2);
1932 if (mode
& M6812_OP_D_IDX_2
)
1934 byte
= (byte
<< 3) | 0xe3;
1936 number_to_chars_bigendian (f
, byte
, 1);
1938 fixup16 (&op
->exp
, 0, 0);
1940 else if (op
->reg1
!= REG_PC
)
1946 number_to_chars_bigendian (f
, byte
, 1);
1947 sym
= op
->exp
.X_add_symbol
;
1948 off
= op
->exp
.X_add_number
;
1949 if (op
->exp
.X_op
!= O_symbol
)
1951 sym
= make_expr_symbol (&op
->exp
);
1954 /* movb/movw cannot be relaxed. */
1958 number_to_chars_bigendian (f
, byte
, 1);
1959 fix_new (frag_now
, f
- frag_now
->fr_literal
, 1,
1960 sym
, off
, 0, BFD_RELOC_M68HC12_5B
);
1965 number_to_chars_bigendian (f
, byte
, 1);
1966 frag_var (rs_machine_dependent
, 2, 2,
1967 ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_UNDF
),
1974 /* movb/movw cannot be relaxed. */
1978 number_to_chars_bigendian (f
, byte
, 1);
1979 fix_new (frag_now
, f
- frag_now
->fr_literal
, 1,
1980 op
->exp
.X_add_symbol
, op
->exp
.X_add_number
, 0, BFD_RELOC_M68HC12_5B
);
1985 number_to_chars_bigendian (f
, byte
, 1);
1986 frag_var (rs_machine_dependent
, 2, 2,
1987 ENCODE_RELAX (STATE_INDEXED_PCREL
, STATE_UNDF
),
1988 op
->exp
.X_add_symbol
,
1989 op
->exp
.X_add_number
, f
);
1995 if (mode
& (M6812_OP_REG
| M6812_OP_D_IDX
))
1997 if (mode
& M6812_OP_D_IDX
)
1999 if (op
->reg1
!= REG_D
)
2000 as_bad (_("Expecting register D for indexed indirect mode."));
2002 as_bad (_("Indexed indirect mode is not allowed for movb/movw."));
2019 as_bad (_("Invalid accumulator register."));
2044 as_bad (_("Invalid indexed register."));
2048 number_to_chars_bigendian (f
, byte
, 1);
2052 as_fatal (_("Addressing mode not implemented yet."));
2056 /* Assemble the 68HC12 register mode byte. */
2058 build_reg_mode (operand
*op
, int format
)
2063 if (format
& M6812_OP_SEX_MARKER
2064 && op
->reg1
!= REG_A
&& op
->reg1
!= REG_B
&& op
->reg1
!= REG_CCR
)
2065 as_bad (_("Invalid source register for this instruction, use 'tfr'."));
2066 else if (op
->reg1
== REG_NONE
|| op
->reg1
== REG_PC
)
2067 as_bad (_("Invalid source register."));
2069 if (format
& M6812_OP_SEX_MARKER
2070 && op
->reg2
!= REG_D
2071 && op
->reg2
!= REG_X
&& op
->reg2
!= REG_Y
&& op
->reg2
!= REG_SP
)
2072 as_bad (_("Invalid destination register for this instruction, use 'tfr'."));
2073 else if (op
->reg2
== REG_NONE
|| op
->reg2
== REG_PC
)
2074 as_bad (_("Invalid destination register."));
2076 byte
= (op
->reg1
<< 4) | (op
->reg2
);
2077 if (format
& M6812_OP_EXG_MARKER
)
2081 number_to_chars_bigendian (f
, byte
, 1);
2085 /* build_insn takes a pointer to the opcode entry in the opcode table,
2086 the array of operand expressions and builds the corresponding instruction.
2087 This operation only deals with non relative jumps insn (need special
2090 build_insn (struct m68hc11_opcode
*opcode
, operand operands
[],
2091 int nb_operands ATTRIBUTE_UNUSED
)
2098 /* Put the page code instruction if there is one. */
2099 format
= opcode
->format
;
2101 if (format
& M6811_OP_BRANCH
)
2102 fix_new (frag_now
, frag_now_fix (), 1,
2103 &abs_symbol
, 0, 1, BFD_RELOC_M68HC11_RL_JUMP
);
2105 if (format
& OP_EXTENDED
)
2109 f
= m68hc11_new_insn (2);
2110 if (format
& M6811_OP_PAGE2
)
2111 page_code
= M6811_OPCODE_PAGE2
;
2112 else if (format
& M6811_OP_PAGE3
)
2113 page_code
= M6811_OPCODE_PAGE3
;
2115 page_code
= M6811_OPCODE_PAGE4
;
2117 number_to_chars_bigendian (f
, page_code
, 1);
2121 f
= m68hc11_new_insn (1);
2123 number_to_chars_bigendian (f
, opcode
->opcode
, 1);
2127 /* The 68HC12 movb and movw instructions are special. We have to handle
2128 them in a special way. */
2129 if (format
& (M6812_OP_IND16_P2
| M6812_OP_IDX_P2
))
2132 if (format
& M6812_OP_IDX
)
2134 build_indexed_byte (&operands
[0], format
, 1);
2136 format
&= ~M6812_OP_IDX
;
2138 if (format
& M6812_OP_IDX_P2
)
2140 build_indexed_byte (&operands
[1], format
, 1);
2142 format
&= ~M6812_OP_IDX_P2
;
2146 if (format
& (M6811_OP_DIRECT
| M6811_OP_IMM8
))
2148 fixup8 (&operands
[i
].exp
,
2149 format
& (M6811_OP_DIRECT
| M6811_OP_IMM8
| M6812_OP_TRAP_ID
),
2153 else if (IS_CALL_SYMBOL (format
) && nb_operands
== 1)
2155 format
&= ~M6812_OP_PAGE
;
2156 fixup24 (&operands
[i
].exp
, format
& M6811_OP_IND16
,
2160 else if (format
& (M6811_OP_IMM16
| M6811_OP_IND16
))
2162 fixup16 (&operands
[i
].exp
,
2163 format
& (M6811_OP_IMM16
| M6811_OP_IND16
| M6812_OP_PAGE
),
2167 else if (format
& (M6811_OP_IX
| M6811_OP_IY
))
2169 if ((format
& M6811_OP_IX
) && (operands
[0].reg1
!= REG_X
))
2170 as_bad (_("Invalid indexed register, expecting register X."));
2171 if ((format
& M6811_OP_IY
) && (operands
[0].reg1
!= REG_Y
))
2172 as_bad (_("Invalid indexed register, expecting register Y."));
2174 fixup8 (&operands
[0].exp
, M6811_OP_IX
, operands
[0].mode
);
2178 (M6812_OP_IDX
| M6812_OP_IDX_2
| M6812_OP_IDX_1
2179 | M6812_OP_D_IDX
| M6812_OP_D_IDX_2
))
2181 build_indexed_byte (&operands
[i
], format
, move_insn
);
2184 else if (format
& M6812_OP_REG
&& current_architecture
& cpu6812
)
2186 build_reg_mode (&operands
[i
], format
);
2189 if (format
& M6811_OP_BITMASK
)
2191 fixup8 (&operands
[i
].exp
, M6811_OP_BITMASK
, operands
[i
].mode
);
2194 if (format
& M6811_OP_JUMP_REL
)
2196 fixup8 (&operands
[i
].exp
, M6811_OP_JUMP_REL
, operands
[i
].mode
);
2198 else if (format
& M6812_OP_IND16_P2
)
2200 fixup16 (&operands
[1].exp
, M6811_OP_IND16
, operands
[1].mode
);
2202 if (format
& M6812_OP_PAGE
)
2204 fixup8 (&operands
[i
].exp
, M6812_OP_PAGE
, operands
[i
].mode
);
2208 /* Opcode identification and operand analysis. */
2210 /* find() gets a pointer to an entry in the opcode table. It must look at all
2211 opcodes with the same name and use the operands to choose the correct
2212 opcode. Returns the opcode pointer if there was a match and 0 if none. */
2213 static struct m68hc11_opcode
*
2214 find (struct m68hc11_opcode_def
*opc
, operand operands
[], int nb_operands
)
2217 struct m68hc11_opcode
*opcode
;
2218 struct m68hc11_opcode
*op_indirect
;
2221 opcode
= opc
->opcode
;
2223 /* Now search the opcode table table for one with operands
2224 that matches what we've got. We're only done if the operands matched so
2225 far AND there are no more to check. */
2226 for (pos
= match
= 0; match
== 0 && pos
< opc
->nb_modes
; pos
++, opcode
++)
2228 int poss_indirect
= 0;
2229 long format
= opcode
->format
;
2233 if (opcode
->format
& M6811_OP_MASK
)
2235 if (opcode
->format
& M6811_OP_BITMASK
)
2237 if (opcode
->format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
2239 if (opcode
->format
& (M6812_OP_IND16_P2
| M6812_OP_IDX_P2
))
2241 if ((opcode
->format
& M6812_OP_PAGE
)
2242 && (!IS_CALL_SYMBOL (opcode
->format
) || nb_operands
== 2))
2245 for (i
= 0; expect
== nb_operands
&& i
< nb_operands
; i
++)
2247 int mode
= operands
[i
].mode
;
2249 if (mode
& M6811_OP_IMM16
)
2252 (M6811_OP_IMM8
| M6811_OP_IMM16
| M6811_OP_BITMASK
))
2256 if (mode
== M6811_OP_DIRECT
)
2258 if (format
& M6811_OP_DIRECT
)
2261 /* If the operand is a page 0 operand, remember a
2262 possible <abs-16> addressing mode. We mark
2263 this and continue to check other operands. */
2264 if (format
& M6811_OP_IND16
2265 && flag_strict_direct_addressing
&& op_indirect
== 0)
2272 if (mode
& M6811_OP_IND16
)
2274 if (i
== 0 && (format
& M6811_OP_IND16
) != 0)
2276 if (i
!= 0 && (format
& M6812_OP_PAGE
) != 0)
2278 if (i
!= 0 && (format
& M6812_OP_IND16_P2
) != 0)
2280 if (i
== 0 && (format
& M6811_OP_BITMASK
))
2283 if (mode
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
2285 if (format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
2288 if (mode
& M6812_OP_REG
)
2291 && (format
& M6812_OP_REG
)
2292 && (operands
[i
].reg2
== REG_NONE
))
2295 && (format
& M6812_OP_REG
)
2296 && (format
& M6812_OP_REG_2
)
2297 && (operands
[i
].reg2
!= REG_NONE
))
2300 && (format
& M6812_OP_IDX
)
2301 && (operands
[i
].reg2
!= REG_NONE
))
2304 && (format
& M6812_OP_IDX
)
2305 && (format
& (M6812_OP_IND16_P2
| M6812_OP_IDX_P2
)))
2308 && (format
& M6812_OP_IDX_P2
))
2312 if (mode
& M6812_OP_IDX
)
2314 if (format
& M6811_OP_IX
&& operands
[i
].reg1
== REG_X
)
2316 if (format
& M6811_OP_IY
&& operands
[i
].reg1
== REG_Y
)
2319 && format
& (M6812_OP_IDX
| M6812_OP_IDX_1
| M6812_OP_IDX_2
)
2320 && (operands
[i
].reg1
== REG_X
2321 || operands
[i
].reg1
== REG_Y
2322 || operands
[i
].reg1
== REG_SP
2323 || operands
[i
].reg1
== REG_PC
))
2325 if (i
== 1 && format
& M6812_OP_IDX_P2
)
2328 if (mode
& format
& (M6812_OP_D_IDX
| M6812_OP_D_IDX_2
))
2333 if (mode
& M6812_AUTO_INC_DEC
)
2336 && format
& (M6812_OP_IDX
| M6812_OP_IDX_1
|
2339 if (i
== 1 && format
& M6812_OP_IDX_P2
)
2344 match
= i
== nb_operands
;
2346 /* Operands are ok but an operand uses page 0 addressing mode
2347 while the insn supports abs-16 mode. Keep a reference to this
2348 insns in case there is no insn supporting page 0 addressing. */
2349 if (match
&& poss_indirect
)
2351 op_indirect
= opcode
;
2358 /* Page 0 addressing is used but not supported by any insn.
2359 If absolute addresses are supported, we use that insn. */
2360 if (match
== 0 && op_indirect
)
2362 opcode
= op_indirect
;
2374 /* Find the real opcode and its associated operands. We use a progressive
2375 approach here. On entry, 'opc' points to the first opcode in the
2376 table that matches the opcode name in the source line. We try to
2377 isolate an operand, find a possible match in the opcode table.
2378 We isolate another operand if no match were found. The table 'operands'
2379 is filled while operands are recognized.
2381 Returns the opcode pointer that matches the opcode name in the
2382 source line and the associated operands. */
2383 static struct m68hc11_opcode
*
2384 find_opcode (struct m68hc11_opcode_def
*opc
, operand operands
[],
2387 struct m68hc11_opcode
*opcode
;
2390 if (opc
->max_operands
== 0)
2396 for (i
= 0; i
< opc
->max_operands
;)
2400 result
= get_operand (&operands
[i
], i
, opc
->format
);
2404 /* Special case where the bitmask of the bclr/brclr
2405 instructions is not introduced by #.
2406 Example: bclr 3,x $80. */
2407 if (i
== 1 && (opc
->format
& M6811_OP_BITMASK
)
2408 && (operands
[i
].mode
& M6811_OP_IND16
))
2410 operands
[i
].mode
= M6811_OP_IMM16
;
2415 if (i
>= opc
->min_operands
)
2417 opcode
= find (opc
, operands
, i
);
2419 /* Another special case for 'call foo,page' instructions.
2420 Since we support 'call foo' and 'call foo,page' we must look
2421 if the optional page specification is present otherwise we will
2422 assemble immediately and treat the page spec as garbage. */
2423 if (opcode
&& !(opcode
->format
& M6812_OP_PAGE
))
2426 if (opcode
&& *input_line_pointer
!= ',')
2430 if (*input_line_pointer
== ',')
2431 input_line_pointer
++;
2437 #define M6812_XBCC_MARKER (M6812_OP_TBCC_MARKER \
2438 | M6812_OP_DBCC_MARKER \
2439 | M6812_OP_IBCC_MARKER)
2441 /* Gas line assembler entry point. */
2443 /* This is the main entry point for the machine-dependent assembler. str
2444 points to a machine-dependent instruction. This function is supposed to
2445 emit the frags/bytes it assembles to. */
2447 md_assemble (char *str
)
2449 struct m68hc11_opcode_def
*opc
;
2450 struct m68hc11_opcode
*opcode
;
2452 unsigned char *op_start
, *save
;
2453 unsigned char *op_end
;
2456 operand operands
[M6811_MAX_OPERANDS
];
2458 int branch_optimize
= 0;
2461 /* Drop leading whitespace. */
2465 /* Find the opcode end and get the opcode in 'name'. The opcode is forced
2466 lower case (the opcode table only has lower case op-codes). */
2467 for (op_start
= op_end
= (unsigned char *) (str
);
2468 *op_end
&& nlen
< 20 && !is_end_of_line
[*op_end
] && *op_end
!= ' ';
2471 name
[nlen
] = TOLOWER (op_start
[nlen
]);
2478 as_bad (_("No instruction or missing opcode."));
2482 /* Find the opcode definition given its name. */
2483 opc
= (struct m68hc11_opcode_def
*) hash_find (m68hc11_hash
, name
);
2485 /* If it's not recognized, look for 'jbsr' and 'jbxx'. These are
2486 pseudo insns for relative branch. For these branchs, we always
2487 optimize them (turned into absolute branchs) even if --short-branchs
2489 if (opc
== NULL
&& name
[0] == 'j' && name
[1] == 'b')
2491 opc
= (struct m68hc11_opcode_def
*) hash_find (m68hc11_hash
, &name
[1]);
2493 && (!(opc
->format
& M6811_OP_JUMP_REL
)
2494 || (opc
->format
& M6811_OP_BITMASK
)))
2497 branch_optimize
= 1;
2500 /* The following test should probably be removed. This is not conform
2501 to Motorola assembler specs. */
2502 if (opc
== NULL
&& flag_mri
)
2504 if (*op_end
== ' ' || *op_end
== '\t')
2506 while (*op_end
== ' ' || *op_end
== '\t')
2511 (is_end_of_line
[op_end
[1]]
2512 || op_end
[1] == ' ' || op_end
[1] == '\t'
2513 || !ISALNUM (op_end
[1])))
2514 && (*op_end
== 'a' || *op_end
== 'b'
2515 || *op_end
== 'A' || *op_end
== 'B'
2516 || *op_end
== 'd' || *op_end
== 'D'
2517 || *op_end
== 'x' || *op_end
== 'X'
2518 || *op_end
== 'y' || *op_end
== 'Y'))
2520 name
[nlen
++] = TOLOWER (*op_end
++);
2522 opc
= (struct m68hc11_opcode_def
*) hash_find (m68hc11_hash
,
2528 /* Identify a possible instruction alias. There are some on the
2529 68HC12 to emulate a few 68HC11 instructions. */
2530 if (opc
== NULL
&& (current_architecture
& cpu6812
))
2534 for (i
= 0; i
< m68hc12_num_alias
; i
++)
2535 if (strcmp (m68hc12_alias
[i
].name
, name
) == 0)
2541 if (opc
== NULL
&& alias_id
< 0)
2543 as_bad (_("Opcode `%s' is not recognized."), name
);
2546 save
= input_line_pointer
;
2547 input_line_pointer
= op_end
;
2552 opcode
= find_opcode (opc
, operands
, &nb_operands
);
2557 if ((opcode
|| alias_id
>= 0) && !flag_mri
)
2559 char *p
= input_line_pointer
;
2561 while (*p
== ' ' || *p
== '\t' || *p
== '\n' || *p
== '\r')
2564 if (*p
!= '\n' && *p
)
2565 as_bad (_("Garbage at end of instruction: `%s'."), p
);
2568 input_line_pointer
= save
;
2572 char *f
= m68hc11_new_insn (m68hc12_alias
[alias_id
].size
);
2574 number_to_chars_bigendian (f
, m68hc12_alias
[alias_id
].code1
, 1);
2575 if (m68hc12_alias
[alias_id
].size
> 1)
2576 number_to_chars_bigendian (f
+ 1, m68hc12_alias
[alias_id
].code2
, 1);
2581 /* Opcode is known but does not have valid operands. Print out the
2582 syntax for this opcode. */
2585 if (flag_print_insn_syntax
)
2586 print_insn_format (name
);
2588 as_bad (_("Invalid operand for `%s'"), name
);
2592 /* Treat dbeq/ibeq/tbeq instructions in a special way. The branch is
2593 relative and must be in the range -256..255 (9-bits). */
2594 if ((opcode
->format
& M6812_XBCC_MARKER
)
2595 && (opcode
->format
& M6811_OP_JUMP_REL
))
2596 build_dbranch_insn (opcode
, operands
, nb_operands
, branch_optimize
);
2598 /* Relative jumps instructions are taken care of separately. We have to make
2599 sure that the relative branch is within the range -128..127. If it's out
2600 of range, the instructions are changed into absolute instructions.
2601 This is not supported for the brset and brclr instructions. */
2602 else if ((opcode
->format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
2603 && !(opcode
->format
& M6811_OP_BITMASK
))
2604 build_jump_insn (opcode
, operands
, nb_operands
, branch_optimize
);
2606 build_insn (opcode
, operands
, nb_operands
);
2610 /* Pseudo op to control the ELF flags. */
2612 s_m68hc11_mode (int x ATTRIBUTE_UNUSED
)
2614 char *name
= input_line_pointer
, ch
;
2616 while (!is_end_of_line
[(unsigned char) *input_line_pointer
])
2617 input_line_pointer
++;
2618 ch
= *input_line_pointer
;
2619 *input_line_pointer
= '\0';
2621 if (strcmp (name
, "mshort") == 0)
2623 elf_flags
&= ~E_M68HC11_I32
;
2625 else if (strcmp (name
, "mlong") == 0)
2627 elf_flags
|= E_M68HC11_I32
;
2629 else if (strcmp (name
, "mshort-double") == 0)
2631 elf_flags
&= ~E_M68HC11_F64
;
2633 else if (strcmp (name
, "mlong-double") == 0)
2635 elf_flags
|= E_M68HC11_F64
;
2639 as_warn (_("Invalid mode: %s\n"), name
);
2641 *input_line_pointer
= ch
;
2642 demand_empty_rest_of_line ();
2645 /* Mark the symbols with STO_M68HC12_FAR to indicate the functions
2646 are using 'rtc' for returning. It is necessary to use 'call'
2647 to invoke them. This is also used by the debugger to correctly
2648 find the stack frame. */
2650 s_m68hc11_mark_symbol (int mark
)
2656 elf_symbol_type
*elfsym
;
2660 name
= input_line_pointer
;
2661 c
= get_symbol_end ();
2662 symbolP
= symbol_find_or_make (name
);
2663 *input_line_pointer
= c
;
2667 bfdsym
= symbol_get_bfdsym (symbolP
);
2668 elfsym
= elf_symbol_from (bfd_asymbol_bfd (bfdsym
), bfdsym
);
2672 /* Mark the symbol far (using rtc for function return). */
2673 elfsym
->internal_elf_sym
.st_other
|= mark
;
2677 input_line_pointer
++;
2681 if (*input_line_pointer
== '\n')
2687 demand_empty_rest_of_line ();
2691 s_m68hc11_relax (int ignore ATTRIBUTE_UNUSED
)
2697 if (ex
.X_op
!= O_symbol
|| ex
.X_add_number
!= 0)
2699 as_bad (_("bad .relax format"));
2700 ignore_rest_of_line ();
2704 fix_new_exp (frag_now
, frag_now_fix (), 2, &ex
, 1,
2705 BFD_RELOC_M68HC11_RL_GROUP
);
2707 demand_empty_rest_of_line ();
2711 /* Relocation, relaxation and frag conversions. */
2713 /* PC-relative offsets are relative to the start of the
2714 next instruction. That is, the address of the offset, plus its
2715 size, since the offset is always the last part of the insn. */
2717 md_pcrel_from (fixS
*fixP
)
2719 if (fixP
->fx_r_type
== BFD_RELOC_M68HC11_RL_JUMP
)
2722 return fixP
->fx_size
+ fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
2725 /* If while processing a fixup, a reloc really needs to be created
2726 then it is done here. */
2728 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
, fixS
*fixp
)
2732 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
2733 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
2734 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
2735 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
2736 if (fixp
->fx_r_type
== 0)
2737 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_16
);
2739 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
2740 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
2742 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2743 _("Relocation %d is not supported by object file format."),
2744 (int) fixp
->fx_r_type
);
2748 /* Since we use Rel instead of Rela, encode the vtable entry to be
2749 used in the relocation's section offset. */
2750 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
2751 reloc
->address
= fixp
->fx_offset
;
2757 /* We need a port-specific relaxation function to cope with sym2 - sym1
2758 relative expressions with both symbols in the same segment (but not
2759 necessarily in the same frag as this insn), for example:
2760 ldab sym2-(sym1-2),pc
2762 The offset can be 5, 9 or 16 bits long. */
2765 m68hc11_relax_frag (segT seg ATTRIBUTE_UNUSED
, fragS
*fragP
,
2766 long stretch ATTRIBUTE_UNUSED
)
2771 const relax_typeS
*this_type
;
2772 const relax_typeS
*start_type
;
2773 relax_substateT next_state
;
2774 relax_substateT this_state
;
2775 const relax_typeS
*table
= TC_GENERIC_RELAX_TABLE
;
2777 /* We only have to cope with frags as prepared by
2778 md_estimate_size_before_relax. The STATE_BITS16 case may geet here
2779 because of the different reasons that it's not relaxable. */
2780 switch (fragP
->fr_subtype
)
2782 case ENCODE_RELAX (STATE_INDEXED_PCREL
, STATE_BITS16
):
2783 case ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS16
):
2784 /* When we get to this state, the frag won't grow any more. */
2787 case ENCODE_RELAX (STATE_INDEXED_PCREL
, STATE_BITS5
):
2788 case ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS5
):
2789 case ENCODE_RELAX (STATE_INDEXED_PCREL
, STATE_BITS9
):
2790 case ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS9
):
2791 if (fragP
->fr_symbol
== NULL
2792 || S_GET_SEGMENT (fragP
->fr_symbol
) != absolute_section
)
2793 as_fatal (_("internal inconsistency problem in %s: fr_symbol %lx"),
2794 __FUNCTION__
, (long) fragP
->fr_symbol
);
2795 symbolP
= fragP
->fr_symbol
;
2796 if (symbol_resolved_p (symbolP
))
2797 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
2799 aim
= S_GET_VALUE (symbolP
);
2803 as_fatal (_("internal inconsistency problem in %s: fr_subtype %d"),
2804 __FUNCTION__
, fragP
->fr_subtype
);
2807 /* The rest is stolen from relax_frag. There's no obvious way to
2808 share the code, but fortunately no requirement to keep in sync as
2809 long as fragP->fr_symbol does not have its segment changed. */
2811 this_state
= fragP
->fr_subtype
;
2812 start_type
= this_type
= table
+ this_state
;
2816 /* Look backwards. */
2817 for (next_state
= this_type
->rlx_more
; next_state
;)
2818 if (aim
>= this_type
->rlx_backward
)
2822 /* Grow to next state. */
2823 this_state
= next_state
;
2824 this_type
= table
+ this_state
;
2825 next_state
= this_type
->rlx_more
;
2830 /* Look forwards. */
2831 for (next_state
= this_type
->rlx_more
; next_state
;)
2832 if (aim
<= this_type
->rlx_forward
)
2836 /* Grow to next state. */
2837 this_state
= next_state
;
2838 this_type
= table
+ this_state
;
2839 next_state
= this_type
->rlx_more
;
2843 growth
= this_type
->rlx_length
- start_type
->rlx_length
;
2845 fragP
->fr_subtype
= this_state
;
2850 md_convert_frag (bfd
*abfd ATTRIBUTE_UNUSED
, asection
*sec ATTRIBUTE_UNUSED
,
2856 char *buffer_address
= fragP
->fr_literal
;
2858 /* Address in object code of the displacement. */
2859 register int object_address
= fragP
->fr_fix
+ fragP
->fr_address
;
2861 buffer_address
+= fragP
->fr_fix
;
2863 /* The displacement of the address, from current location. */
2864 value
= S_GET_VALUE (fragP
->fr_symbol
);
2865 disp
= (value
+ fragP
->fr_offset
) - object_address
;
2867 switch (fragP
->fr_subtype
)
2869 case ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_BYTE
):
2870 fragP
->fr_opcode
[1] = disp
;
2873 case ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_WORD
):
2874 /* This relax is only for bsr and bra. */
2875 assert (IS_OPCODE (fragP
->fr_opcode
[0], M6811_BSR
)
2876 || IS_OPCODE (fragP
->fr_opcode
[0], M6811_BRA
)
2877 || IS_OPCODE (fragP
->fr_opcode
[0], M6812_BSR
));
2879 fragP
->fr_opcode
[0] = convert_branch (fragP
->fr_opcode
[0]);
2881 fix_new (fragP
, fragP
->fr_fix
- 1, 2,
2882 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_16
);
2886 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
, STATE_BYTE
):
2887 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
, STATE_BYTE
):
2888 fragP
->fr_opcode
[1] = disp
;
2891 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
, STATE_WORD
):
2892 /* Invert branch. */
2893 fragP
->fr_opcode
[0] ^= 1;
2894 fragP
->fr_opcode
[1] = 3; /* Branch offset. */
2895 buffer_address
[0] = M6811_JMP
;
2896 fix_new (fragP
, fragP
->fr_fix
+ 1, 2,
2897 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_16
);
2901 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
, STATE_WORD
):
2902 /* Translate branch into a long branch. */
2903 fragP
->fr_opcode
[1] = fragP
->fr_opcode
[0];
2904 fragP
->fr_opcode
[0] = M6811_OPCODE_PAGE2
;
2906 fixp
= fix_new (fragP
, fragP
->fr_fix
, 2,
2907 fragP
->fr_symbol
, fragP
->fr_offset
, 1,
2908 BFD_RELOC_16_PCREL
);
2909 fixp
->fx_pcrel_adjust
= 2;
2913 case ENCODE_RELAX (STATE_INDEXED_PCREL
, STATE_BITS5
):
2914 if (fragP
->fr_symbol
!= 0
2915 && S_GET_SEGMENT (fragP
->fr_symbol
) != absolute_section
)
2919 case ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS5
):
2920 fragP
->fr_opcode
[0] = fragP
->fr_opcode
[0] << 6;
2921 fragP
->fr_opcode
[0] |= value
& 0x1f;
2924 case ENCODE_RELAX (STATE_INDEXED_PCREL
, STATE_BITS9
):
2925 /* For a PC-relative offset, use the displacement with a -1 correction
2926 to take into account the additional byte of the insn. */
2927 if (fragP
->fr_symbol
!= 0
2928 && S_GET_SEGMENT (fragP
->fr_symbol
) != absolute_section
)
2932 case ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS9
):
2933 fragP
->fr_opcode
[0] = (fragP
->fr_opcode
[0] << 3);
2934 fragP
->fr_opcode
[0] |= 0xE0;
2935 fragP
->fr_opcode
[0] |= (value
>> 8) & 1;
2936 fragP
->fr_opcode
[1] = value
;
2940 case ENCODE_RELAX (STATE_INDEXED_PCREL
, STATE_BITS16
):
2941 case ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS16
):
2942 fragP
->fr_opcode
[0] = (fragP
->fr_opcode
[0] << 3);
2943 fragP
->fr_opcode
[0] |= 0xe2;
2944 if ((fragP
->fr_opcode
[0] & 0x0ff) == 0x0fa
2945 && fragP
->fr_symbol
!= 0
2946 && S_GET_SEGMENT (fragP
->fr_symbol
) != absolute_section
)
2948 fixp
= fix_new (fragP
, fragP
->fr_fix
, 2,
2949 fragP
->fr_symbol
, fragP
->fr_offset
,
2950 1, BFD_RELOC_16_PCREL
);
2954 fix_new (fragP
, fragP
->fr_fix
, 2,
2955 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_16
);
2960 case ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_BYTE
):
2962 fragP
->fr_opcode
[0] |= 0x10;
2964 fragP
->fr_opcode
[1] = disp
& 0x0FF;
2967 case ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_WORD
):
2968 /* Invert branch. */
2969 fragP
->fr_opcode
[0] ^= 0x20;
2970 fragP
->fr_opcode
[1] = 3; /* Branch offset. */
2971 buffer_address
[0] = M6812_JMP
;
2972 fix_new (fragP
, fragP
->fr_fix
+ 1, 2,
2973 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_16
);
2982 /* On an ELF system, we can't relax a weak symbol. The weak symbol
2983 can be overridden at final link time by a non weak symbol. We can
2984 relax externally visible symbol because there is no shared library
2985 and such symbol can't be overridden (unless they are weak). */
2987 relaxable_symbol (symbolS
*symbol
)
2989 return ! S_IS_WEAK (symbol
);
2992 /* Force truly undefined symbols to their maximum size, and generally set up
2993 the frag list to be relaxed. */
2995 md_estimate_size_before_relax (fragS
*fragP
, asection
*segment
)
2997 if (RELAX_LENGTH (fragP
->fr_subtype
) == STATE_UNDF
)
2999 if (S_GET_SEGMENT (fragP
->fr_symbol
) != segment
3000 || !relaxable_symbol (fragP
->fr_symbol
)
3001 || (segment
!= absolute_section
3002 && RELAX_STATE (fragP
->fr_subtype
) == STATE_INDEXED_OFFSET
))
3004 /* Non-relaxable cases. */
3006 char *buffer_address
;
3008 old_fr_fix
= fragP
->fr_fix
;
3009 buffer_address
= fragP
->fr_fix
+ fragP
->fr_literal
;
3011 switch (RELAX_STATE (fragP
->fr_subtype
))
3013 case STATE_PC_RELATIVE
:
3015 /* This relax is only for bsr and bra. */
3016 assert (IS_OPCODE (fragP
->fr_opcode
[0], M6811_BSR
)
3017 || IS_OPCODE (fragP
->fr_opcode
[0], M6811_BRA
)
3018 || IS_OPCODE (fragP
->fr_opcode
[0], M6812_BSR
));
3020 if (flag_fixed_branchs
)
3021 as_bad_where (fragP
->fr_file
, fragP
->fr_line
,
3022 _("bra or bsr with undefined symbol."));
3024 /* The symbol is undefined or in a separate section.
3025 Turn bra into a jmp and bsr into a jsr. The insn
3026 becomes 3 bytes long (instead of 2). A fixup is
3027 necessary for the unresolved symbol address. */
3028 fragP
->fr_opcode
[0] = convert_branch (fragP
->fr_opcode
[0]);
3030 fix_new (fragP
, fragP
->fr_fix
- 1, 2, fragP
->fr_symbol
,
3031 fragP
->fr_offset
, 0, BFD_RELOC_16
);
3035 case STATE_CONDITIONAL_BRANCH
:
3036 assert (current_architecture
& cpu6811
);
3038 fragP
->fr_opcode
[0] ^= 1; /* Reverse sense of branch. */
3039 fragP
->fr_opcode
[1] = 3; /* Skip next jmp insn (3 bytes). */
3041 /* Don't use fr_opcode[2] because this may be
3042 in a different frag. */
3043 buffer_address
[0] = M6811_JMP
;
3046 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
3047 fragP
->fr_offset
, 0, BFD_RELOC_16
);
3051 case STATE_INDEXED_OFFSET
:
3052 assert (current_architecture
& cpu6812
);
3054 if (fragP
->fr_symbol
3055 && S_GET_SEGMENT (fragP
->fr_symbol
) == absolute_section
)
3057 fragP
->fr_subtype
= ENCODE_RELAX (STATE_INDEXED_OFFSET
,
3059 /* Return the size of the variable part of the frag. */
3060 return md_relax_table
[fragP
->fr_subtype
].rlx_length
;
3064 /* Switch the indexed operation to 16-bit mode. */
3065 fragP
->fr_opcode
[0] = fragP
->fr_opcode
[0] << 3;
3066 fragP
->fr_opcode
[0] |= 0xe2;
3067 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
3068 fragP
->fr_offset
, 0, BFD_RELOC_16
);
3073 case STATE_INDEXED_PCREL
:
3074 assert (current_architecture
& cpu6812
);
3076 if (fragP
->fr_symbol
3077 && S_GET_SEGMENT (fragP
->fr_symbol
) == absolute_section
)
3079 fragP
->fr_subtype
= ENCODE_RELAX (STATE_INDEXED_PCREL
,
3081 /* Return the size of the variable part of the frag. */
3082 return md_relax_table
[fragP
->fr_subtype
].rlx_length
;
3088 fragP
->fr_opcode
[0] = fragP
->fr_opcode
[0] << 3;
3089 fragP
->fr_opcode
[0] |= 0xe2;
3090 fixp
= fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
3091 fragP
->fr_offset
, 1, BFD_RELOC_16_PCREL
);
3096 case STATE_XBCC_BRANCH
:
3097 assert (current_architecture
& cpu6812
);
3099 fragP
->fr_opcode
[0] ^= 0x20; /* Reverse sense of branch. */
3100 fragP
->fr_opcode
[1] = 3; /* Skip next jmp insn (3 bytes). */
3102 /* Don't use fr_opcode[2] because this may be
3103 in a different frag. */
3104 buffer_address
[0] = M6812_JMP
;
3107 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
3108 fragP
->fr_offset
, 0, BFD_RELOC_16
);
3112 case STATE_CONDITIONAL_BRANCH_6812
:
3113 assert (current_architecture
& cpu6812
);
3115 /* Translate into a lbcc branch. */
3116 fragP
->fr_opcode
[1] = fragP
->fr_opcode
[0];
3117 fragP
->fr_opcode
[0] = M6811_OPCODE_PAGE2
;
3119 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
3120 fragP
->fr_offset
, 1, BFD_RELOC_16_PCREL
);
3125 as_fatal (_("Subtype %d is not recognized."), fragP
->fr_subtype
);
3129 /* Return the growth in the fixed part of the frag. */
3130 return fragP
->fr_fix
- old_fr_fix
;
3133 /* Relaxable cases. */
3134 switch (RELAX_STATE (fragP
->fr_subtype
))
3136 case STATE_PC_RELATIVE
:
3137 /* This relax is only for bsr and bra. */
3138 assert (IS_OPCODE (fragP
->fr_opcode
[0], M6811_BSR
)
3139 || IS_OPCODE (fragP
->fr_opcode
[0], M6811_BRA
)
3140 || IS_OPCODE (fragP
->fr_opcode
[0], M6812_BSR
));
3142 fragP
->fr_subtype
= ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_BYTE
);
3145 case STATE_CONDITIONAL_BRANCH
:
3146 assert (current_architecture
& cpu6811
);
3148 fragP
->fr_subtype
= ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
,
3152 case STATE_INDEXED_OFFSET
:
3153 assert (current_architecture
& cpu6812
);
3155 fragP
->fr_subtype
= ENCODE_RELAX (STATE_INDEXED_OFFSET
,
3159 case STATE_INDEXED_PCREL
:
3160 assert (current_architecture
& cpu6812
);
3162 fragP
->fr_subtype
= ENCODE_RELAX (STATE_INDEXED_PCREL
,
3166 case STATE_XBCC_BRANCH
:
3167 assert (current_architecture
& cpu6812
);
3169 fragP
->fr_subtype
= ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_BYTE
);
3172 case STATE_CONDITIONAL_BRANCH_6812
:
3173 assert (current_architecture
& cpu6812
);
3175 fragP
->fr_subtype
= ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
,
3181 if (fragP
->fr_subtype
>= sizeof (md_relax_table
) / sizeof (md_relax_table
[0]))
3182 as_fatal (_("Subtype %d is not recognized."), fragP
->fr_subtype
);
3184 /* Return the size of the variable part of the frag. */
3185 return md_relax_table
[fragP
->fr_subtype
].rlx_length
;
3188 /* See whether we need to force a relocation into the output file. */
3190 tc_m68hc11_force_relocation (fixS
*fixP
)
3192 if (fixP
->fx_r_type
== BFD_RELOC_M68HC11_RL_GROUP
)
3195 return generic_force_reloc (fixP
);
3198 /* Here we decide which fixups can be adjusted to make them relative
3199 to the beginning of the section instead of the symbol. Basically
3200 we need to make sure that the linker relaxation is done
3201 correctly, so in some cases we force the original symbol to be
3204 tc_m68hc11_fix_adjustable (fixS
*fixP
)
3206 switch (fixP
->fx_r_type
)
3208 /* For the linker relaxation to work correctly, these relocs
3209 need to be on the symbol itself. */
3211 case BFD_RELOC_M68HC11_RL_JUMP
:
3212 case BFD_RELOC_M68HC11_RL_GROUP
:
3213 case BFD_RELOC_VTABLE_INHERIT
:
3214 case BFD_RELOC_VTABLE_ENTRY
:
3217 /* The memory bank addressing translation also needs the original
3219 case BFD_RELOC_M68HC11_LO16
:
3220 case BFD_RELOC_M68HC11_PAGE
:
3221 case BFD_RELOC_M68HC11_24
:
3230 md_apply_fix3 (fixS
*fixP
, valueT
*valP
, segT seg ATTRIBUTE_UNUSED
)
3233 long value
= * valP
;
3236 if (fixP
->fx_addsy
== (symbolS
*) NULL
)
3239 /* We don't actually support subtracting a symbol. */
3240 if (fixP
->fx_subsy
!= (symbolS
*) NULL
)
3241 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("Expression too complex."));
3243 op_type
= fixP
->fx_r_type
;
3245 /* Patch the instruction with the resolved operand. Elf relocation
3246 info will also be generated to take care of linker/loader fixups.
3247 The 68HC11 addresses only 64Kb, we are only concerned by 8 and 16-bit
3248 relocs. BFD_RELOC_8 is basically used for .page0 access (the linker
3249 will warn for overflows). BFD_RELOC_8_PCREL should not be generated
3250 because it's either resolved or turned out into non-relative insns (see
3251 relax table, bcc, bra, bsr transformations)
3253 The BFD_RELOC_32 is necessary for the support of --gstabs. */
3254 where
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
3256 switch (fixP
->fx_r_type
)
3259 bfd_putb32 ((bfd_vma
) value
, (unsigned char *) where
);
3263 case BFD_RELOC_M68HC11_24
:
3264 bfd_putb16 ((bfd_vma
) (value
& 0x0ffff), (unsigned char *) where
);
3265 ((bfd_byte
*) where
)[2] = ((value
>> 16) & 0x0ff);
3269 case BFD_RELOC_16_PCREL
:
3270 case BFD_RELOC_M68HC11_LO16
:
3271 bfd_putb16 ((bfd_vma
) value
, (unsigned char *) where
);
3272 if (value
< -65537 || value
> 65535)
3273 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3274 _("Value out of 16-bit range."));
3277 case BFD_RELOC_M68HC11_HI8
:
3281 case BFD_RELOC_M68HC11_LO8
:
3283 case BFD_RELOC_M68HC11_PAGE
:
3285 bfd_putb8 ((bfd_vma
) value
, (unsigned char *) where
);
3287 ((bfd_byte
*) where
)[0] = (bfd_byte
) value
;
3290 case BFD_RELOC_8_PCREL
:
3292 bfd_putb8 ((bfd_vma
) value
, (unsigned char *) where
);
3294 ((bfd_byte
*) where
)[0] = (bfd_byte
) value
;
3296 if (value
< -128 || value
> 127)
3297 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3298 _("Value %ld too large for 8-bit PC-relative branch."),
3302 case BFD_RELOC_M68HC11_3B
:
3303 if (value
<= 0 || value
> 8)
3304 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3305 _("Auto increment/decrement offset '%ld' is out of range."),
3312 where
[0] = where
[0] | (value
& 0x07);
3315 case BFD_RELOC_M68HC12_5B
:
3316 if (value
< -16 || value
> 15)
3317 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3318 _("Offset out of 5-bit range for movw/movb insn: %ld"),
3323 where
[0] |= (0x10 | (16 + value
));
3326 case BFD_RELOC_M68HC11_RL_JUMP
:
3327 case BFD_RELOC_M68HC11_RL_GROUP
:
3328 case BFD_RELOC_VTABLE_INHERIT
:
3329 case BFD_RELOC_VTABLE_ENTRY
:
3334 as_fatal (_("Line %d: unknown relocation type: 0x%x."),
3335 fixP
->fx_line
, fixP
->fx_r_type
);
3339 /* Set the ELF specific flags. */
3341 m68hc11_elf_final_processing (void)
3343 if (current_architecture
& cpu6812s
)
3344 elf_flags
|= EF_M68HCS12_MACH
;
3345 elf_elfheader (stdoutput
)->e_flags
&= ~EF_M68HC11_ABI
;
3346 elf_elfheader (stdoutput
)->e_flags
|= elf_flags
;