1 /* tc-m68hc11.c -- Assembler code for the Motorola 68HC11 & 68HC12.
2 Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
3 Written by Stephane Carrez (stcarrez@worldnet.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. */
26 #include "opcode/m68hc11.h"
27 #include "dwarf2dbg.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_XBCC_BRANCH (4)
40 #define STATE_CONDITIONAL_BRANCH_6812 (5)
42 #define STATE_BYTE (0)
43 #define STATE_BITS5 (0)
44 #define STATE_WORD (1)
45 #define STATE_BITS9 (1)
46 #define STATE_LONG (2)
47 #define STATE_BITS16 (2)
48 #define STATE_UNDF (3) /* Symbol undefined in pass1 */
50 /* This macro has no side-effects. */
51 #define ENCODE_RELAX(what,length) (((what) << 2) + (length))
52 #define RELAX_STATE(s) ((s) >> 2)
53 #define RELAX_LENGTH(s) ((s) & 3)
55 #define IS_OPCODE(C1,C2) (((C1) & 0x0FF) == ((C2) & 0x0FF))
57 /* This table describes how you change sizes for the various types of variable
58 size expressions. This version only supports two kinds. */
61 How far Forward this mode will reach.
62 How far Backward this mode will reach.
63 How many bytes this mode will add to the size of the frag.
64 Which mode to go to if the offset won't fit in this one. */
66 relax_typeS md_relax_table
[] = {
67 {1, 1, 0, 0}, /* First entries aren't used. */
68 {1, 1, 0, 0}, /* For no good reason except. */
69 {1, 1, 0, 0}, /* that the VAX doesn't either. */
73 These insns are translated into b!cc +3 jmp L. */
74 {(127), (-128), 0, ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
, STATE_WORD
)},
79 /* Relax for bsr <L> and bra <L>.
80 These insns are translated into jsr and jmp. */
81 {(127), (-128), 0, ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_WORD
)},
86 /* Relax for indexed offset: 5-bits, 9-bits, 16-bits. */
87 {(15), (-16), 0, ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS9
)},
88 {(255), (-256), 1, ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS16
)},
92 /* Relax for dbeq/ibeq/tbeq r,<L>:
93 These insns are translated into db!cc +3 jmp L. */
94 {(255), (-256), 0, ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_WORD
)},
99 /* Relax for bcc <L> on 68HC12.
100 These insns are translated into lbcc <L>. */
101 {(127), (-128), 0, ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
, STATE_WORD
)},
108 /* 68HC11 and 68HC12 registers. They are numbered according to the 68HC12. */
109 typedef enum register_id
{
121 typedef struct operand
{
128 struct m68hc11_opcode_def
{
134 struct m68hc11_opcode
*opcode
;
137 static struct m68hc11_opcode_def
*m68hc11_opcode_defs
= 0;
138 static int m68hc11_nb_opcode_defs
= 0;
140 typedef struct alias
{
145 static alias alias_opcodes
[] = {
152 /* Local functions. */
153 static register_id reg_name_search
PARAMS ((char *));
154 static register_id register_name
PARAMS ((void));
155 static int check_range
PARAMS ((long, int));
156 static void print_opcode_list
PARAMS ((void));
157 static void get_default_target
PARAMS ((void));
158 static void print_insn_format
PARAMS ((char *));
159 static int get_operand
PARAMS ((operand
*, int, long));
160 static void fixup8
PARAMS ((expressionS
*, int, int));
161 static void fixup16
PARAMS ((expressionS
*, int, int));
162 static struct m68hc11_opcode
*find_opcode
163 PARAMS ((struct m68hc11_opcode_def
*, operand
*, int *));
164 static void build_jump_insn
165 PARAMS ((struct m68hc11_opcode
*, operand
*, int, int));
166 static void build_insn
167 PARAMS ((struct m68hc11_opcode
*, operand
*, int));
169 /* Controls whether relative branches can be turned into long branches.
170 When the relative offset is too large, the insn are changed:
178 Setting the flag forbidds this. */
179 static short flag_fixed_branchs
= 0;
181 /* Force to use long jumps (absolute) instead of relative branches. */
182 static short flag_force_long_jumps
= 0;
184 /* Change the direct addressing mode into an absolute addressing mode
185 when the insn does not support direct addressing.
186 For example, "clr *ZD0" is normally not possible and is changed
188 static short flag_strict_direct_addressing
= 1;
190 /* When an opcode has invalid operand, print out the syntax of the opcode
192 static short flag_print_insn_syntax
= 0;
194 /* Dumps the list of instructions with syntax and then exit:
195 1 -> Only dumps the list (sorted by name)
196 2 -> Generate an example (or test) that can be compiled. */
197 static short flag_print_opcodes
= 0;
199 /* Opcode hash table. */
200 static struct hash_control
*m68hc11_hash
;
202 /* Current cpu (either cpu6811 or cpu6812). This is determined automagically
203 by 'get_default_target' by looking at default BFD vector. This is overriden
204 with the -m<cpu> option. */
205 static int current_architecture
= 0;
207 /* Default cpu determined by 'get_default_target'. */
208 static const char *default_cpu
;
210 /* Number of opcodes in the sorted table (filtered by current cpu). */
211 static int num_opcodes
;
213 /* The opcodes sorted by name and filtered by current cpu. */
214 static struct m68hc11_opcode
*m68hc11_sorted_opcodes
;
216 /* These are the machine dependent pseudo-ops. These are included so
217 the assembler can work on the output from the SUN C compiler, which
220 /* This table describes all the machine specific pseudo-ops the assembler
221 has to support. The fields are:
222 pseudo-op name without dot
223 function to call to execute this pseudo-op
224 Integer arg to pass to the function. */
225 const pseudo_typeS md_pseudo_table
[] = {
226 /* The following pseudo-ops are supported for MRI compatibility. */
229 {"fcc", stringer
, 1},
232 /* Dwarf2 support for Gcc. */
233 {"file", dwarf2_directive_file
, 0},
234 {"loc", dwarf2_directive_loc
, 0},
237 {"xrefb", s_ignore
, 0}, /* Same as xref */
242 /* Options and initialization. */
244 CONST
char *md_shortopts
= "Sm:";
246 struct option md_longopts
[] = {
247 #define OPTION_FORCE_LONG_BRANCH (OPTION_MD_BASE)
248 {"force-long-branchs", no_argument
, NULL
, OPTION_FORCE_LONG_BRANCH
},
250 #define OPTION_SHORT_BRANCHS (OPTION_MD_BASE + 1)
251 {"short-branchs", no_argument
, NULL
, OPTION_SHORT_BRANCHS
},
253 #define OPTION_STRICT_DIRECT_MODE (OPTION_MD_BASE + 2)
254 {"strict-direct-mode", no_argument
, NULL
, OPTION_STRICT_DIRECT_MODE
},
256 #define OPTION_PRINT_INSN_SYNTAX (OPTION_MD_BASE + 3)
257 {"print-insn-syntax", no_argument
, NULL
, OPTION_PRINT_INSN_SYNTAX
},
259 #define OPTION_PRINT_OPCODES (OPTION_MD_BASE + 4)
260 {"print-opcodes", no_argument
, NULL
, OPTION_PRINT_OPCODES
},
262 #define OPTION_GENERATE_EXAMPLE (OPTION_MD_BASE + 5)
263 {"generate-example", no_argument
, NULL
, OPTION_GENERATE_EXAMPLE
},
265 {NULL
, no_argument
, NULL
, 0}
267 size_t md_longopts_size
= sizeof (md_longopts
);
269 /* Get the target cpu for the assembler. This is based on the configure
270 options and on the -m68hc11/-m68hc12 option. If no option is specified,
271 we must get the default. */
273 m68hc11_arch_format ()
275 get_default_target ();
276 if (current_architecture
& cpu6811
)
277 return "elf32-m68hc11";
279 return "elf32-m68hc12";
282 enum bfd_architecture
285 get_default_target ();
286 if (current_architecture
& cpu6811
)
287 return bfd_arch_m68hc11
;
289 return bfd_arch_m68hc12
;
298 /* Listing header selected according to cpu. */
300 m68hc11_listing_header ()
302 if (current_architecture
& cpu6811
)
303 return "M68HC11 GAS ";
305 return "M68HC12 GAS ";
309 md_show_usage (stream
)
312 get_default_target ();
313 fprintf (stream
, _("\
314 Motorola 68HC11/68HC12 options:\n\
315 -m68hc11 | -m68hc12 specify the processor [default %s]\n\
316 --force-long-branchs always turn relative branchs into absolute ones\n\
317 -S,--short-branchs do not turn relative branchs into absolute ones\n\
318 when the offset is out of range\n\
319 --strict-direct-mode do not turn the direct mode into extended mode\n\
320 when the instruction does not support direct mode\n\
321 --print-insn-syntax print the syntax of instruction in case of error\n\
322 --print-opcodes print the list of instructions with syntax\n\
323 --generate-example generate an example of each instruction\n\
324 (used for testing)\n"), default_cpu
);
328 /* Try to identify the default target based on the BFD library. */
330 get_default_target ()
332 const bfd_target
*target
;
335 if (current_architecture
!= 0)
338 default_cpu
= "unknown";
339 target
= bfd_find_target (0, &abfd
);
340 if (target
&& target
->name
)
342 if (strcmp (target
->name
, "elf32-m68hc12") == 0)
344 current_architecture
= cpu6812
;
345 default_cpu
= "m68hc12";
347 else if (strcmp (target
->name
, "elf32-m68hc11") == 0)
349 current_architecture
= cpu6811
;
350 default_cpu
= "m68hc11";
354 as_bad (_("Default target `%s' is not supported."), target
->name
);
360 m68hc11_print_statistics (file
)
364 struct m68hc11_opcode_def
*opc
;
366 hash_print_statistics (file
, "opcode table", m68hc11_hash
);
368 opc
= m68hc11_opcode_defs
;
369 if (opc
== 0 || m68hc11_nb_opcode_defs
== 0)
372 /* Dump the opcode statistics table. */
373 fprintf (file
, _("Name # Modes Min ops Max ops Modes mask # Used\n"));
374 for (i
= 0; i
< m68hc11_nb_opcode_defs
; i
++, opc
++)
376 fprintf (file
, "%-7.7s %5d %7d %7d 0x%08lx %7d\n",
379 opc
->min_operands
, opc
->max_operands
, opc
->format
, opc
->used
);
384 md_parse_option (c
, arg
)
388 get_default_target ();
391 /* -S means keep external to 2 bit offset rather than 16 bit one. */
392 case OPTION_SHORT_BRANCHS
:
394 flag_fixed_branchs
= 1;
397 case OPTION_FORCE_LONG_BRANCH
:
398 flag_force_long_jumps
= 1;
401 case OPTION_PRINT_INSN_SYNTAX
:
402 flag_print_insn_syntax
= 1;
405 case OPTION_PRINT_OPCODES
:
406 flag_print_opcodes
= 1;
409 case OPTION_STRICT_DIRECT_MODE
:
410 flag_strict_direct_addressing
= 0;
413 case OPTION_GENERATE_EXAMPLE
:
414 flag_print_opcodes
= 2;
418 if (strcasecmp (arg
, "68hc11") == 0)
419 current_architecture
= cpu6811
;
420 else if (strcasecmp (arg
, "68hc12") == 0)
421 current_architecture
= cpu6812
;
423 as_bad (_("Option `%s' is not recognized."), arg
);
434 md_undefined_symbol (name
)
435 char *name ATTRIBUTE_UNUSED
;
440 /* Equal to MAX_PRECISION in atof-ieee.c. */
441 #define MAX_LITTLENUMS 6
443 /* Turn a string in input_line_pointer into a floating point constant
444 of type TYPE, and store the appropriate bytes in *LITP. The number
445 of LITTLENUMS emitted is stored in *SIZEP. An error message is
446 returned, or NULL on OK. */
448 md_atof (type
, litP
, sizeP
)
454 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
455 LITTLENUM_TYPE
*wordP
;
486 return _("Bad call to MD_ATOF()");
488 t
= atof_ieee (input_line_pointer
, type
, words
);
490 input_line_pointer
= t
;
492 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
493 for (wordP
= words
; prec
--;)
495 md_number_to_chars (litP
, (long) (*wordP
++), sizeof (LITTLENUM_TYPE
));
496 litP
+= sizeof (LITTLENUM_TYPE
);
502 md_section_align (seg
, addr
)
506 int align
= bfd_get_section_alignment (stdoutput
, seg
);
507 return ((addr
+ (1 << align
) - 1) & (-1 << align
));
511 cmp_opcode (op1
, op2
)
512 struct m68hc11_opcode
*op1
;
513 struct m68hc11_opcode
*op2
;
515 return strcmp (op1
->name
, op2
->name
);
518 /* Initialize the assembler. Create the opcode hash table
519 (sorted on the names) with the M6811 opcode table
520 (from opcode library). */
524 char *prev_name
= "";
525 struct m68hc11_opcode
*opcodes
;
526 struct m68hc11_opcode_def
*opc
= 0;
529 get_default_target ();
531 m68hc11_hash
= hash_new ();
533 /* Get a writable copy of the opcode table and sort it on the names. */
534 opcodes
= (struct m68hc11_opcode
*) xmalloc (m68hc11_num_opcodes
*
537 m68hc11_sorted_opcodes
= opcodes
;
539 for (i
= 0; i
< m68hc11_num_opcodes
; i
++)
541 if (m68hc11_opcodes
[i
].arch
& current_architecture
)
543 opcodes
[num_opcodes
] = m68hc11_opcodes
[i
];
544 if (opcodes
[num_opcodes
].name
[0] == 'b'
545 && opcodes
[num_opcodes
].format
& M6811_OP_JUMP_REL
546 && !(opcodes
[num_opcodes
].format
& M6811_OP_BITMASK
))
549 opcodes
[num_opcodes
] = m68hc11_opcodes
[i
];
552 for (j
= 0; alias_opcodes
[j
].name
!= 0; j
++)
553 if (strcmp (m68hc11_opcodes
[i
].name
, alias_opcodes
[j
].name
) == 0)
555 opcodes
[num_opcodes
] = m68hc11_opcodes
[i
];
556 opcodes
[num_opcodes
].name
= alias_opcodes
[j
].alias
;
562 qsort (opcodes
, num_opcodes
, sizeof (struct m68hc11_opcode
), cmp_opcode
);
564 opc
= (struct m68hc11_opcode_def
*)
565 xmalloc (num_opcodes
* sizeof (struct m68hc11_opcode_def
));
566 m68hc11_opcode_defs
= opc
--;
568 /* Insert unique names into hash table. The M6811 instruction set
569 has several identical opcode names that have different opcodes based
570 on the operands. This hash table then provides a quick index to
571 the first opcode with a particular name in the opcode table. */
572 for (i
= 0; i
< num_opcodes
; i
++, opcodes
++)
576 if (strcmp (prev_name
, opcodes
->name
))
578 prev_name
= (char *) opcodes
->name
;
582 opc
->min_operands
= 100;
583 opc
->max_operands
= 0;
585 opc
->opcode
= opcodes
;
587 hash_insert (m68hc11_hash
, opcodes
->name
, (char *) opc
);
590 opc
->format
|= opcodes
->format
;
592 /* See how many operands this opcode needs. */
594 if (opcodes
->format
& M6811_OP_MASK
)
596 if (opcodes
->format
& M6811_OP_BITMASK
)
598 if (opcodes
->format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
600 if (opcodes
->format
& (M6812_OP_IND16_P2
| M6812_OP_IDX_P2
))
603 if (expect
< opc
->min_operands
)
604 opc
->min_operands
= expect
;
605 if (expect
> opc
->max_operands
)
606 opc
->max_operands
= expect
;
609 m68hc11_nb_opcode_defs
= opc
- m68hc11_opcode_defs
;
611 if (flag_print_opcodes
)
613 print_opcode_list ();
619 m68hc11_init_after_args ()
625 /* Return a string that represents the operand format for the instruction.
626 When example is true, this generates an example of operand. This is used
627 to give an example and also to generate a test. */
629 print_opcode_format (opcode
, example
)
630 struct m68hc11_opcode
*opcode
;
633 static char buf
[128];
634 int format
= opcode
->format
;
639 if (format
& M6811_OP_IMM8
)
642 sprintf (p
, "#%d", rand () & 0x0FF);
644 strcpy (p
, _("#<imm8>"));
648 if (format
& M6811_OP_IMM16
)
651 sprintf (p
, "#%d", rand () & 0x0FFFF);
653 strcpy (p
, _("#<imm16>"));
657 if (format
& M6811_OP_IX
)
660 sprintf (p
, "%d,X", rand () & 0x0FF);
662 strcpy (p
, _("<imm8>,X"));
666 if (format
& M6811_OP_IY
)
669 sprintf (p
, "%d,X", rand () & 0x0FF);
671 strcpy (p
, _("<imm8>,X"));
675 if (format
& M6812_OP_IDX
)
678 sprintf (p
, "%d,X", rand () & 0x0FF);
684 if (format
& M6811_OP_DIRECT
)
687 sprintf (p
, "*Z%d", rand () & 0x0FF);
689 strcpy (p
, _("*<abs8>"));
693 if (format
& M6811_OP_BITMASK
)
699 sprintf (p
, "#$%02x", rand () & 0x0FF);
701 strcpy (p
, _("#<mask>"));
704 if (format
& M6811_OP_JUMP_REL
)
708 if (format
& M6811_OP_IND16
)
711 sprintf (p
, _("symbol%d"), rand () & 0x0FF);
713 strcpy (p
, _("<abs>"));
718 if (format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
722 if (format
& M6811_OP_BITMASK
)
724 sprintf (p
, ".+%d", rand () & 0x7F);
728 sprintf (p
, "L%d", rand () & 0x0FF);
732 strcpy (p
, _("<label>"));
738 /* Prints the list of instructions with the possible operands. */
743 char *prev_name
= "";
744 struct m68hc11_opcode
*opcodes
;
745 int example
= flag_print_opcodes
== 2;
748 printf (_("# Example of `%s' instructions\n\t.sect .text\n_start:\n"),
751 opcodes
= m68hc11_sorted_opcodes
;
753 /* Walk the list sorted on names (by md_begin). We only report
754 one instruction per line, and we collect the different operand
756 for (i
= 0; i
< num_opcodes
; i
++, opcodes
++)
758 char *fmt
= print_opcode_format (opcodes
, example
);
762 printf ("L%d:\t", i
);
763 printf ("%s %s\n", opcodes
->name
, fmt
);
767 if (strcmp (prev_name
, opcodes
->name
))
772 printf ("%-5.5s ", opcodes
->name
);
773 prev_name
= (char *) opcodes
->name
;
776 printf (" [%s]", fmt
);
782 /* Print the instruction format. This operation is called when some
783 instruction is not correct. Instruction format is printed as an
786 print_insn_format (name
)
789 struct m68hc11_opcode_def
*opc
;
790 struct m68hc11_opcode
*opcode
;
793 opc
= (struct m68hc11_opcode_def
*) hash_find (m68hc11_hash
, name
);
796 as_bad (_("Instruction `%s' is not recognized."), name
);
799 opcode
= opc
->opcode
;
801 as_bad (_("Instruction formats for `%s':"), name
);
806 fmt
= print_opcode_format (opcode
, 0, 0);
807 sprintf (buf
, "\t%-5.5s %s", opcode
->name
, fmt
);
812 while (strcmp (opcode
->name
, name
) == 0);
815 /* Analysis of 68HC11 and 68HC12 operands. */
817 /* reg_name_search() finds the register number given its name.
818 Returns the register number or REG_NONE on failure. */
820 reg_name_search (name
)
823 if (strcasecmp (name
, "x") == 0 || strcasecmp (name
, "ix") == 0)
825 if (strcasecmp (name
, "y") == 0 || strcasecmp (name
, "iy") == 0)
827 if (strcasecmp (name
, "a") == 0)
829 if (strcasecmp (name
, "b") == 0)
831 if (strcasecmp (name
, "d") == 0)
833 if (strcasecmp (name
, "sp") == 0)
835 if (strcasecmp (name
, "pc") == 0)
837 if (strcasecmp (name
, "ccr") == 0)
847 while (*p
== ' ' || *p
== '\t')
853 /* Check the string at input_line_pointer
854 to see if it is a valid register name. */
858 register_id reg_number
;
859 char c
, *p
= input_line_pointer
;
861 if (!is_name_beginner (*p
++))
864 while (is_part_of_name (*p
++))
871 /* Look to see if it's in the register table. */
872 reg_number
= reg_name_search (input_line_pointer
);
873 if (reg_number
!= REG_NONE
)
878 input_line_pointer
= p
;
887 /* Parse a string of operands and return an array of expressions.
889 Operand mode[0] mode[1] exp[0] exp[1]
890 #n M6811_OP_IMM16 - O_*
891 *<exp> M6811_OP_DIRECT - O_*
892 .{+-}<exp> M6811_OP_JUMP_REL - O_*
893 <exp> M6811_OP_IND16 - O_*
894 ,r N,r M6812_OP_IDX M6812_OP_REG O_constant O_register
895 n,-r M6812_PRE_DEC M6812_OP_REG O_constant O_register
896 n,+r M6812_PRE_INC " "
897 n,r- M6812_POST_DEC " "
898 n,r+ M6812_POST_INC " "
899 A,r B,r D,r M6811_OP_REG M6812_OP_REG O_register O_register
900 [D,r] M6811_OP_IDX_2 M6812_OP_REG O_register O_register
901 [n,r] M6811_OP_IDX_1 M6812_OP_REG O_constant O_register */
903 get_operand (oper
, which
, opmode
)
908 char *p
= input_line_pointer
;
912 oper
->exp
.X_op
= O_absent
;
913 oper
->reg1
= REG_NONE
;
914 oper
->reg2
= REG_NONE
;
915 mode
= M6811_OP_NONE
;
919 if (*p
== 0 || *p
== '\n' || *p
== '\r')
921 input_line_pointer
= p
;
925 if (*p
== '*' && (opmode
& (M6811_OP_DIRECT
| M6811_OP_IND16
)))
927 mode
= M6811_OP_DIRECT
;
932 if (!(opmode
& (M6811_OP_IMM8
| M6811_OP_IMM16
| M6811_OP_BITMASK
)))
934 as_bad (_("Immediate operand is not allowed for operand %d."),
939 mode
= M6811_OP_IMM16
;
941 if (strncmp (p
, "%hi", 3) == 0)
944 mode
|= M6811_OP_HIGH_ADDR
;
946 else if (strncmp (p
, "%lo", 3) == 0)
949 mode
|= M6811_OP_LOW_ADDR
;
952 else if (*p
== '.' && (p
[1] == '+' || p
[1] == '-'))
955 mode
= M6811_OP_JUMP_REL
;
959 if (current_architecture
& cpu6811
)
960 as_bad (_("Indirect indexed addressing is not valid for 68HC11."));
963 mode
= M6812_OP_IDX_2
;
966 else if (*p
== ',') /* Special handling of ,x and ,y. */
969 input_line_pointer
= p
;
971 reg
= register_name ();
975 oper
->exp
.X_op
= O_constant
;
976 oper
->exp
.X_add_number
= 0;
977 oper
->mode
= M6812_OP_IDX
;
980 as_bad (_("Spurious `,' or bad indirect register addressing mode."));
983 input_line_pointer
= p
;
985 if (mode
== M6811_OP_NONE
|| mode
== M6812_OP_IDX_2
)
986 reg
= register_name ();
992 p
= skip_whites (input_line_pointer
);
993 if (*p
== ']' && mode
== M6812_OP_IDX_2
)
996 (_("Missing second register or offset for indexed-indirect mode."));
1001 oper
->mode
= mode
| M6812_OP_REG
;
1004 if (mode
== M6812_OP_IDX_2
)
1006 as_bad (_("Missing second register for indexed-indirect mode."));
1013 input_line_pointer
= p
;
1014 reg
= register_name ();
1015 if (reg
!= REG_NONE
)
1017 p
= skip_whites (input_line_pointer
);
1018 if (mode
== M6812_OP_IDX_2
)
1022 as_bad (_("Missing `]' to close indexed-indirect mode."));
1027 input_line_pointer
= p
;
1035 /* In MRI mode, isolate the operand because we can't distinguish
1036 operands from comments. */
1041 p
= skip_whites (p
);
1042 while (*p
&& *p
!= ' ' && *p
!= '\t')
1051 /* Parse as an expression. */
1052 expression (&oper
->exp
);
1061 expression (&oper
->exp
);
1064 if (oper
->exp
.X_op
== O_illegal
)
1066 as_bad (_("Illegal operand."));
1069 else if (oper
->exp
.X_op
== O_absent
)
1071 as_bad (_("Missing operand."));
1075 p
= input_line_pointer
;
1077 if (mode
== M6811_OP_NONE
|| mode
== M6811_OP_DIRECT
1078 || mode
== M6812_OP_IDX_2
)
1080 p
= skip_whites (input_line_pointer
);
1084 int possible_mode
= M6811_OP_NONE
;
1085 char *old_input_line
;
1088 /* 68HC12 pre increment or decrement. */
1089 if (mode
== M6811_OP_NONE
)
1093 possible_mode
= M6812_PRE_DEC
;
1098 possible_mode
= M6812_PRE_INC
;
1101 p
= skip_whites (p
);
1103 old_input_line
= input_line_pointer
;
1104 input_line_pointer
= p
;
1105 reg
= register_name ();
1107 /* Backtrack if we have a valid constant expression and
1108 it does not correspond to the offset of the 68HC12 indexed
1109 addressing mode (as in N,x). */
1110 if (reg
== REG_NONE
&& mode
== M6811_OP_NONE
1111 && possible_mode
!= M6811_OP_NONE
)
1113 oper
->mode
= M6811_OP_IND16
| M6811_OP_JUMP_REL
;
1114 input_line_pointer
= skip_whites (old_input_line
);
1118 if (possible_mode
!= M6811_OP_NONE
)
1119 mode
= possible_mode
;
1121 if ((current_architecture
& cpu6811
)
1122 && possible_mode
!= M6811_OP_NONE
)
1123 as_bad (_("Pre-increment mode is not valid for 68HC11"));
1125 if (which
== 0 && opmode
& M6812_OP_IDX_P2
1126 && reg
!= REG_X
&& reg
!= REG_Y
1127 && reg
!= REG_PC
&& reg
!= REG_SP
)
1130 input_line_pointer
= p
;
1133 if (reg
== REG_NONE
&& mode
!= M6811_OP_DIRECT
1134 && !(mode
== M6811_OP_NONE
&& opmode
& M6811_OP_IND16
))
1136 as_bad (_("Wrong register in register indirect mode."));
1139 if (mode
== M6812_OP_IDX_2
)
1141 p
= skip_whites (input_line_pointer
);
1144 as_bad (_("Missing `]' to close register indirect operand."));
1147 input_line_pointer
= p
;
1149 if (reg
!= REG_NONE
)
1152 if (mode
== M6811_OP_NONE
)
1154 p
= input_line_pointer
;
1157 mode
= M6812_POST_DEC
;
1159 if (current_architecture
& cpu6811
)
1161 (_("Post-decrement mode is not valid for 68HC11."));
1165 mode
= M6812_POST_INC
;
1167 if (current_architecture
& cpu6811
)
1169 (_("Post-increment mode is not valid for 68HC11."));
1172 mode
= M6812_OP_IDX
;
1174 input_line_pointer
= p
;
1177 mode
|= M6812_OP_IDX
;
1184 if (mode
== M6812_OP_D_IDX_2
)
1186 as_bad (_("Invalid indexed indirect mode."));
1191 /* If the mode is not known until now, this is either a label
1192 or an indirect address. */
1193 if (mode
== M6811_OP_NONE
)
1194 mode
= M6811_OP_IND16
| M6811_OP_JUMP_REL
;
1196 p
= input_line_pointer
;
1197 while (*p
== ' ' || *p
== '\t')
1199 input_line_pointer
= p
;
1205 #define M6812_AUTO_INC_DEC (M6812_PRE_INC | M6812_PRE_DEC \
1206 | M6812_POST_INC | M6812_POST_DEC)
1208 /* Checks that the number 'num' fits for a given mode. */
1210 check_range (num
, mode
)
1214 /* Auto increment and decrement are ok for [-8..8] without 0. */
1215 if (mode
& M6812_AUTO_INC_DEC
)
1216 return (num
!= 0 && num
<= 8 && num
>= -8);
1218 /* The 68HC12 supports 5, 9 and 16-bit offsets. */
1219 if (mode
& (M6812_INDEXED_IND
| M6812_INDEXED
| M6812_OP_IDX
))
1220 mode
= M6811_OP_IND16
;
1222 if (mode
& M6812_OP_JUMP_REL16
)
1223 mode
= M6811_OP_IND16
;
1229 case M6811_OP_DIRECT
:
1230 return (num
>= 0 && num
<= 255) ? 1 : 0;
1232 case M6811_OP_BITMASK
:
1234 return (((num
& 0xFFFFFF00) == 0) || ((num
& 0xFFFFFF00) == 0xFFFFFF00))
1237 case M6811_OP_JUMP_REL
:
1238 return (num
>= -128 && num
<= 127) ? 1 : 0;
1240 case M6811_OP_IND16
:
1241 case M6811_OP_IMM16
:
1242 return (((num
& 0xFFFF0000) == 0) || ((num
& 0xFFFF0000) == 0xFFFF0000))
1245 case M6812_OP_IBCC_MARKER
:
1246 case M6812_OP_TBCC_MARKER
:
1247 case M6812_OP_DBCC_MARKER
:
1248 return (num
>= -256 && num
<= 255) ? 1 : 0;
1250 case M6812_OP_TRAP_ID
:
1251 return ((num
>= 0x30 && num
<= 0x39)
1252 || (num
>= 0x40 && num
<= 0x0ff)) ? 1 : 0;
1259 /* Gas fixup generation. */
1261 /* Put a 1 byte expression described by 'oper'. If this expression contains
1262 unresolved symbols, generate an 8-bit fixup. */
1264 fixup8 (oper
, mode
, opmode
)
1273 if (oper
->X_op
== O_constant
)
1275 if (mode
& M6812_OP_TRAP_ID
1276 && !check_range (oper
->X_add_number
, M6812_OP_TRAP_ID
))
1278 static char trap_id_warn_once
= 0;
1280 as_bad (_("Trap id `%ld' is out of range."), oper
->X_add_number
);
1281 if (trap_id_warn_once
== 0)
1283 trap_id_warn_once
= 1;
1284 as_bad (_("Trap id must be within [0x30..0x39] or [0x40..0xff]."));
1288 if (!(mode
& M6812_OP_TRAP_ID
)
1289 && !check_range (oper
->X_add_number
, mode
))
1291 as_bad (_("Operand out of 8-bit range: `%ld'."), oper
->X_add_number
);
1293 number_to_chars_bigendian (f
, oper
->X_add_number
& 0x0FF, 1);
1295 else if (oper
->X_op
!= O_register
)
1297 if (mode
& M6812_OP_TRAP_ID
)
1298 as_bad (_("The trap id must be a constant."));
1300 if (mode
== M6811_OP_JUMP_REL
)
1304 fixp
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 1,
1305 oper
, true, BFD_RELOC_8_PCREL
);
1306 fixp
->fx_pcrel_adjust
= 1;
1310 /* Now create an 8-bit fixup. If there was some %hi or %lo
1311 modifier, generate the reloc accordingly. */
1312 fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 1,
1314 ((opmode
& M6811_OP_HIGH_ADDR
)
1315 ? BFD_RELOC_M68HC11_HI8
1316 : ((opmode
& M6811_OP_LOW_ADDR
)
1317 ? BFD_RELOC_M68HC11_LO8
: BFD_RELOC_8
)));
1319 number_to_chars_bigendian (f
, 0, 1);
1323 as_fatal (_("Operand `%x' not recognized in fixup8."), oper
->X_op
);
1327 /* Put a 2 byte expression described by 'oper'. If this expression contains
1328 unresolved symbols, generate a 16-bit fixup. */
1330 fixup16 (oper
, mode
, opmode
)
1333 int opmode ATTRIBUTE_UNUSED
;
1339 if (oper
->X_op
== O_constant
)
1341 if (!check_range (oper
->X_add_number
, mode
))
1343 as_bad (_("Operand out of 16-bit range: `%ld'."),
1344 oper
->X_add_number
);
1346 number_to_chars_bigendian (f
, oper
->X_add_number
& 0x0FFFF, 2);
1348 else if (oper
->X_op
!= O_register
)
1352 /* Now create a 16-bit fixup. */
1353 fixp
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 2,
1355 (mode
& M6812_OP_JUMP_REL16
? true : false),
1356 (mode
& M6812_OP_JUMP_REL16
1357 ? BFD_RELOC_16_PCREL
: BFD_RELOC_16
));
1358 number_to_chars_bigendian (f
, 0, 2);
1359 if (mode
& M6812_OP_JUMP_REL16
)
1360 fixp
->fx_pcrel_adjust
= 2;
1364 as_fatal (_("Operand `%x' not recognized in fixup16."), oper
->X_op
);
1368 /* 68HC11 and 68HC12 code generation. */
1370 /* Translate the short branch/bsr instruction into a long branch. */
1371 static unsigned char
1372 convert_branch (code
)
1375 if (IS_OPCODE (code
, M6812_BSR
))
1377 else if (IS_OPCODE (code
, M6811_BSR
))
1379 else if (IS_OPCODE (code
, M6811_BRA
))
1380 return (current_architecture
& cpu6812
) ? M6812_JMP
: M6811_JMP
;
1382 as_fatal (_("Unexpected branch conversion with `%x'"), code
);
1384 /* Keep gcc happy. */
1388 /* Start a new insn that contains at least 'size' bytes. Record the
1389 line information of that insn in the dwarf2 debug sections. */
1391 m68hc11_new_insn (size
)
1396 f
= frag_more (size
);
1398 dwarf2_emit_insn (size
);
1403 /* Builds a jump instruction (bra, bcc, bsr). */
1405 build_jump_insn (opcode
, operands
, nb_operands
, jmp_mode
)
1406 struct m68hc11_opcode
*opcode
;
1415 /* The relative branch convertion is not supported for
1417 assert ((opcode
->format
& M6811_OP_BITMASK
) == 0);
1418 assert (nb_operands
== 1);
1419 assert (operands
[0].reg1
== REG_NONE
&& operands
[0].reg2
== REG_NONE
);
1421 code
= opcode
->opcode
;
1423 n
= operands
[0].exp
.X_add_number
;
1425 /* Turn into a long branch:
1426 - when force long branch option (and not for jbcc pseudos),
1427 - when jbcc and the constant is out of -128..127 range,
1428 - when branch optimization is allowed and branch out of range. */
1429 if ((jmp_mode
== 0 && flag_force_long_jumps
)
1430 || (operands
[0].exp
.X_op
== O_constant
1431 && (!check_range (n
, opcode
->format
) &&
1432 (jmp_mode
== 1 || flag_fixed_branchs
== 0))))
1434 if (code
== M6811_BSR
|| code
== M6811_BRA
|| code
== M6812_BSR
)
1436 code
= convert_branch (code
);
1438 f
= m68hc11_new_insn (1);
1439 number_to_chars_bigendian (f
, code
, 1);
1441 else if (current_architecture
& cpu6812
)
1443 /* 68HC12: translate the bcc into a lbcc. */
1444 f
= m68hc11_new_insn (2);
1445 number_to_chars_bigendian (f
, M6811_OPCODE_PAGE2
, 1);
1446 number_to_chars_bigendian (f
+ 1, code
, 1);
1447 fixup16 (&operands
[0].exp
, M6812_OP_JUMP_REL16
,
1448 M6812_OP_JUMP_REL16
);
1453 /* 68HC11: translate the bcc into b!cc +3; jmp <L>. */
1454 f
= m68hc11_new_insn (3);
1456 number_to_chars_bigendian (f
, code
, 1);
1457 number_to_chars_bigendian (f
+ 1, 3, 1);
1458 number_to_chars_bigendian (f
+ 2, M6811_JMP
, 1);
1460 fixup16 (&operands
[0].exp
, M6811_OP_IND16
, M6811_OP_IND16
);
1464 /* Branch with a constant that must fit in 8-bits. */
1465 if (operands
[0].exp
.X_op
== O_constant
)
1467 if (!check_range (n
, opcode
->format
))
1469 as_bad (_("Operand out of range for a relative branch: `%ld'"),
1472 else if (opcode
->format
& M6812_OP_JUMP_REL16
)
1474 f
= m68hc11_new_insn (4);
1475 number_to_chars_bigendian (f
, M6811_OPCODE_PAGE2
, 1);
1476 number_to_chars_bigendian (f
+ 1, code
, 1);
1477 number_to_chars_bigendian (f
+ 2, n
& 0x0ffff, 2);
1481 f
= m68hc11_new_insn (2);
1482 number_to_chars_bigendian (f
, code
, 1);
1483 number_to_chars_bigendian (f
+ 1, n
& 0x0FF, 1);
1486 else if (opcode
->format
& M6812_OP_JUMP_REL16
)
1488 f
= m68hc11_new_insn (2);
1489 number_to_chars_bigendian (f
, M6811_OPCODE_PAGE2
, 1);
1490 number_to_chars_bigendian (f
+ 1, code
, 1);
1491 fixup16 (&operands
[0].exp
, M6812_OP_JUMP_REL16
, M6812_OP_JUMP_REL16
);
1497 /* Branch offset must fit in 8-bits, don't do some relax. */
1498 if (jmp_mode
== 0 && flag_fixed_branchs
)
1500 opcode
= m68hc11_new_insn (1);
1501 number_to_chars_bigendian (opcode
, code
, 1);
1502 fixup8 (&operands
[0].exp
, M6811_OP_JUMP_REL
, M6811_OP_JUMP_REL
);
1505 /* bra/bsr made be changed into jmp/jsr. */
1506 else if (code
== M6811_BSR
|| code
== M6811_BRA
|| code
== M6812_BSR
)
1508 opcode
= m68hc11_new_insn (2);
1509 number_to_chars_bigendian (opcode
, code
, 1);
1510 number_to_chars_bigendian (opcode
+ 1, 0, 1);
1511 frag_var (rs_machine_dependent
, 2, 1,
1512 ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_UNDF
),
1513 operands
[0].exp
.X_add_symbol
, (offsetT
) n
, opcode
);
1515 else if (current_architecture
& cpu6812
)
1517 opcode
= m68hc11_new_insn (2);
1518 number_to_chars_bigendian (opcode
, code
, 1);
1519 number_to_chars_bigendian (opcode
+ 1, 0, 1);
1520 frag_var (rs_machine_dependent
, 2, 2,
1521 ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
, STATE_UNDF
),
1522 operands
[0].exp
.X_add_symbol
, (offsetT
) n
, opcode
);
1526 opcode
= m68hc11_new_insn (2);
1527 number_to_chars_bigendian (opcode
, code
, 1);
1528 number_to_chars_bigendian (opcode
+ 1, 0, 1);
1529 frag_var (rs_machine_dependent
, 3, 3,
1530 ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
, STATE_UNDF
),
1531 operands
[0].exp
.X_add_symbol
, (offsetT
) n
, opcode
);
1536 /* Builds a dbne/dbeq/tbne/tbeq instruction. */
1538 build_dbranch_insn (opcode
, operands
, nb_operands
, jmp_mode
)
1539 struct m68hc11_opcode
*opcode
;
1548 /* The relative branch convertion is not supported for
1550 assert ((opcode
->format
& M6811_OP_BITMASK
) == 0);
1551 assert (nb_operands
== 2);
1552 assert (operands
[0].reg1
!= REG_NONE
);
1554 code
= opcode
->opcode
& 0x0FF;
1556 f
= m68hc11_new_insn (1);
1557 number_to_chars_bigendian (f
, code
, 1);
1559 n
= operands
[1].exp
.X_add_number
;
1560 code
= operands
[0].reg1
;
1562 if (operands
[0].reg1
== REG_NONE
|| operands
[0].reg1
== REG_CCR
1563 || operands
[0].reg1
== REG_PC
)
1564 as_bad (_("Invalid register for dbcc/tbcc instruction."));
1566 if (opcode
->format
& M6812_OP_IBCC_MARKER
)
1568 else if (opcode
->format
& M6812_OP_TBCC_MARKER
)
1571 if (!(opcode
->format
& M6812_OP_EQ_MARKER
))
1574 /* Turn into a long branch:
1575 - when force long branch option (and not for jbcc pseudos),
1576 - when jdbcc and the constant is out of -256..255 range,
1577 - when branch optimization is allowed and branch out of range. */
1578 if ((jmp_mode
== 0 && flag_force_long_jumps
)
1579 || (operands
[1].exp
.X_op
== O_constant
1580 && (!check_range (n
, M6812_OP_IBCC_MARKER
) &&
1581 (jmp_mode
== 1 || flag_fixed_branchs
== 0))))
1585 number_to_chars_bigendian (f
, code
, 1);
1586 number_to_chars_bigendian (f
+ 1, M6812_JMP
, 1);
1587 fixup16 (&operands
[0].exp
, M6811_OP_IND16
, M6811_OP_IND16
);
1591 /* Branch with a constant that must fit in 9-bits. */
1592 if (operands
[1].exp
.X_op
== O_constant
)
1594 if (!check_range (n
, M6812_OP_IBCC_MARKER
))
1596 as_bad (_("Operand out of range for a relative branch: `%ld'"),
1605 number_to_chars_bigendian (f
, code
, 1);
1606 number_to_chars_bigendian (f
+ 1, n
& 0x0FF, 1);
1611 /* Branch offset must fit in 8-bits, don't do some relax. */
1612 if (jmp_mode
== 0 && flag_fixed_branchs
)
1614 fixup8 (&operands
[0].exp
, M6811_OP_JUMP_REL
, M6811_OP_JUMP_REL
);
1620 number_to_chars_bigendian (f
, code
, 1);
1621 number_to_chars_bigendian (f
+ 1, 0, 1);
1622 frag_var (rs_machine_dependent
, 3, 3,
1623 ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_UNDF
),
1624 operands
[1].exp
.X_add_symbol
, (offsetT
) n
, f
);
1629 #define OP_EXTENDED (M6811_OP_PAGE2 | M6811_OP_PAGE3 | M6811_OP_PAGE4)
1631 /* Assemble the post index byte for 68HC12 extended addressing modes. */
1633 build_indexed_byte (op
, format
, move_insn
)
1635 int format ATTRIBUTE_UNUSED
;
1638 unsigned char byte
= 0;
1643 val
= op
->exp
.X_add_number
;
1645 if (mode
& M6812_AUTO_INC_DEC
)
1648 if (mode
& (M6812_POST_INC
| M6812_POST_DEC
))
1651 if (op
->exp
.X_op
== O_constant
)
1653 if (!check_range (val
, mode
))
1655 as_bad (_("Increment/decrement value is out of range: `%ld'."),
1658 if (mode
& (M6812_POST_INC
| M6812_PRE_INC
))
1659 byte
|= (val
- 1) & 0x07;
1661 byte
|= (8 - ((val
) & 7)) | 0x8;
1666 as_fatal (_("Expecting a register."));
1681 as_bad (_("Invalid register for post/pre increment."));
1686 number_to_chars_bigendian (f
, byte
, 1);
1690 if (mode
& M6812_OP_IDX
)
1711 as_bad (_("Invalid register."));
1714 if (op
->exp
.X_op
== O_constant
)
1716 if (!check_range (val
, M6812_OP_IDX
))
1718 as_bad (_("Offset out of 16-bit range: %ld."), val
);
1721 if (move_insn
&& !(val
>= -16 && val
<= 15))
1723 as_bad (_("Offset out of 5-bit range for movw/movb insn: %ld."),
1728 if (val
>= -16 && val
<= 15 && !(mode
& M6812_OP_IDX_2
))
1733 number_to_chars_bigendian (f
, byte
, 1);
1736 else if (val
>= -256 && val
<= 255 && !(mode
& M6812_OP_IDX_2
))
1743 number_to_chars_bigendian (f
, byte
, 1);
1744 number_to_chars_bigendian (f
+ 1, val
& 0x0FF, 1);
1750 if (mode
& M6812_OP_IDX_2
)
1756 number_to_chars_bigendian (f
, byte
, 1);
1757 number_to_chars_bigendian (f
+ 1, val
& 0x0FFFF, 2);
1761 if (op
->reg1
!= REG_PC
)
1763 byte
= (byte
<< 3) | 0xe2;
1765 number_to_chars_bigendian (f
, byte
, 1);
1768 fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 2,
1769 &op
->exp
, false, BFD_RELOC_16
);
1770 number_to_chars_bigendian (f
, 0, 2);
1775 number_to_chars_bigendian (f
, byte
, 1);
1776 frag_var (rs_machine_dependent
, 2, 2,
1777 ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_UNDF
),
1778 op
->exp
.X_add_symbol
,
1779 op
->exp
.X_add_number
, f
);
1784 if (mode
& M6812_OP_REG
)
1786 if (mode
& M6812_OP_IDX_2
)
1788 if (op
->reg1
!= REG_D
)
1789 as_bad (_("Expecting register D for indexed indirect mode."));
1791 as_bad (_("Indexed indirect mode is not allowed for movb/movw."));
1808 as_bad (_("Invalid accumulator register."));
1833 as_bad (_("Invalid indexed register."));
1837 number_to_chars_bigendian (f
, byte
, 1);
1841 as_fatal (_("Addressing mode not implemented yet."));
1845 /* Assemble the 68HC12 register mode byte. */
1847 build_reg_mode (op
, format
)
1854 if (format
& M6812_OP_SEX_MARKER
1855 && op
->reg1
!= REG_A
&& op
->reg1
!= REG_B
&& op
->reg1
!= REG_CCR
)
1856 as_bad (_("Invalid source register for this instruction, use 'tfr'."));
1857 else if (op
->reg1
== REG_NONE
|| op
->reg1
== REG_PC
)
1858 as_bad (_("Invalid source register."));
1860 if (format
& M6812_OP_SEX_MARKER
1861 && op
->reg2
!= REG_D
1862 && op
->reg2
!= REG_X
&& op
->reg2
!= REG_Y
&& op
->reg2
!= REG_SP
)
1863 as_bad (_("Invalid destination register for this instruction, use 'tfr'."));
1864 else if (op
->reg2
== REG_NONE
|| op
->reg2
== REG_PC
)
1865 as_bad (_("Invalid destination register."));
1867 byte
= (op
->reg1
<< 4) | (op
->reg2
);
1868 if (format
& M6812_OP_EXG_MARKER
)
1872 number_to_chars_bigendian (f
, byte
, 1);
1876 /* build_insn takes a pointer to the opcode entry in the opcode table,
1877 the array of operand expressions and builds the correspding instruction.
1878 This operation only deals with non relative jumps insn (need special
1881 build_insn (opcode
, operands
, nb_operands
)
1882 struct m68hc11_opcode
*opcode
;
1884 int nb_operands ATTRIBUTE_UNUSED
;
1891 /* Put the page code instruction if there is one. */
1892 format
= opcode
->format
;
1893 if (format
& OP_EXTENDED
)
1897 f
= m68hc11_new_insn (2);
1898 if (format
& M6811_OP_PAGE2
)
1899 page_code
= M6811_OPCODE_PAGE2
;
1900 else if (format
& M6811_OP_PAGE3
)
1901 page_code
= M6811_OPCODE_PAGE3
;
1903 page_code
= M6811_OPCODE_PAGE4
;
1905 number_to_chars_bigendian (f
, page_code
, 1);
1909 f
= m68hc11_new_insn (1);
1911 number_to_chars_bigendian (f
, opcode
->opcode
, 1);
1915 /* The 68HC12 movb and movw instructions are special. We have to handle
1916 them in a special way. */
1917 if (format
& (M6812_OP_IND16_P2
| M6812_OP_IDX_P2
))
1920 if (format
& M6812_OP_IDX
)
1922 build_indexed_byte (&operands
[0], format
, 1);
1924 format
&= ~M6812_OP_IDX
;
1926 if (format
& M6812_OP_IDX_P2
)
1928 build_indexed_byte (&operands
[1], format
, 1);
1930 format
&= ~M6812_OP_IDX_P2
;
1934 if (format
& (M6811_OP_DIRECT
| M6811_OP_IMM8
))
1936 fixup8 (&operands
[i
].exp
,
1937 format
& (M6811_OP_DIRECT
| M6811_OP_IMM8
| M6812_OP_TRAP_ID
),
1941 else if (format
& (M6811_OP_IMM16
| M6811_OP_IND16
))
1943 fixup16 (&operands
[i
].exp
, format
& (M6811_OP_IMM16
| M6811_OP_IND16
),
1947 else if (format
& (M6811_OP_IX
| M6811_OP_IY
))
1949 if ((format
& M6811_OP_IX
) && (operands
[0].reg1
!= REG_X
))
1950 as_bad (_("Invalid indexed register, expecting register X."));
1951 if ((format
& M6811_OP_IY
) && (operands
[0].reg1
!= REG_Y
))
1952 as_bad (_("Invalid indexed register, expecting register Y."));
1954 fixup8 (&operands
[0].exp
, M6811_OP_IX
, operands
[0].mode
);
1958 (M6812_OP_IDX
| M6812_OP_IDX_2
| M6812_OP_IDX_1
| M6812_OP_D_IDX
))
1960 build_indexed_byte (&operands
[i
], format
, move_insn
);
1963 else if (format
& M6812_OP_REG
&& current_architecture
& cpu6812
)
1965 build_reg_mode (&operands
[i
], format
);
1968 if (format
& M6811_OP_BITMASK
)
1970 fixup8 (&operands
[i
].exp
, M6811_OP_BITMASK
, operands
[i
].mode
);
1973 if (format
& M6811_OP_JUMP_REL
)
1975 fixup8 (&operands
[i
].exp
, M6811_OP_JUMP_REL
, operands
[i
].mode
);
1977 else if (format
& M6812_OP_IND16_P2
)
1979 fixup16 (&operands
[1].exp
, M6811_OP_IND16
, operands
[1].mode
);
1983 /* Opcode identification and operand analysis. */
1985 /* find() gets a pointer to an entry in the opcode table. It must look at all
1986 opcodes with the same name and use the operands to choose the correct
1987 opcode. Returns the opcode pointer if there was a match and 0 if none. */
1988 static struct m68hc11_opcode
*
1989 find (opc
, operands
, nb_operands
)
1990 struct m68hc11_opcode_def
*opc
;
1995 struct m68hc11_opcode
*opcode
;
1996 struct m68hc11_opcode
*op_indirect
;
1999 opcode
= opc
->opcode
;
2001 /* Now search the opcode table table for one with operands
2002 that matches what we've got. We're only done if the operands matched so
2003 far AND there are no more to check. */
2004 for (pos
= match
= 0; match
== 0 && pos
< opc
->nb_modes
; pos
++, opcode
++)
2006 int poss_indirect
= 0;
2007 long format
= opcode
->format
;
2011 if (opcode
->format
& M6811_OP_MASK
)
2013 if (opcode
->format
& M6811_OP_BITMASK
)
2015 if (opcode
->format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
2017 if (opcode
->format
& (M6812_OP_IND16_P2
| M6812_OP_IDX_P2
))
2020 for (i
= 0; expect
== nb_operands
&& i
< nb_operands
; i
++)
2022 int mode
= operands
[i
].mode
;
2024 if (mode
& M6811_OP_IMM16
)
2027 (M6811_OP_IMM8
| M6811_OP_IMM16
| M6811_OP_BITMASK
))
2031 if (mode
== M6811_OP_DIRECT
)
2033 if (format
& M6811_OP_DIRECT
)
2036 /* If the operand is a page 0 operand, remember a
2037 possible <abs-16> addressing mode. We mark
2038 this and continue to check other operands. */
2039 if (format
& M6811_OP_IND16
2040 && flag_strict_direct_addressing
&& op_indirect
== 0)
2047 if (mode
& M6811_OP_IND16
)
2049 if (i
== 0 && (format
& M6811_OP_IND16
) != 0)
2051 if (i
!= 0 && (format
& M6812_OP_IND16_P2
) != 0)
2053 if (i
== 0 && (format
& M6811_OP_BITMASK
))
2056 if (mode
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
2058 if (format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
2061 if (mode
& M6812_OP_REG
)
2064 && (format
& M6812_OP_REG
)
2065 && (operands
[i
].reg2
== REG_NONE
))
2068 && (format
& M6812_OP_REG
)
2069 && (format
& M6812_OP_REG_2
)
2070 && (operands
[i
].reg2
!= REG_NONE
))
2073 && (format
& M6812_OP_IDX
)
2074 && (operands
[i
].reg2
!= REG_NONE
))
2077 && (format
& M6812_OP_D_IDX
))
2080 && (format
& M6812_OP_IDX
)
2081 && (format
& (M6812_OP_IND16_P2
| M6812_OP_IDX_P2
)))
2084 && (format
& M6812_OP_IDX_P2
))
2088 if (mode
& M6812_OP_IDX
)
2090 if (format
& M6811_OP_IX
&& operands
[i
].reg1
== REG_X
)
2092 if (format
& M6811_OP_IY
&& operands
[i
].reg1
== REG_Y
)
2095 && format
& (M6812_OP_IDX
| M6812_OP_IDX_1
| M6812_OP_IDX_2
)
2096 && (operands
[i
].reg1
== REG_X
2097 || operands
[i
].reg1
== REG_Y
2098 || operands
[i
].reg1
== REG_SP
2099 || operands
[i
].reg1
== REG_PC
))
2101 if (i
== 1 && format
& M6812_OP_IDX_P2
)
2104 if (mode
& M6812_AUTO_INC_DEC
)
2107 && format
& (M6812_OP_IDX
| M6812_OP_IDX_1
|
2110 if (i
== 1 && format
& M6812_OP_IDX_P2
)
2115 match
= i
== nb_operands
;
2117 /* Operands are ok but an operand uses page 0 addressing mode
2118 while the insn supports abs-16 mode. Keep a reference to this
2119 insns in case there is no insn supporting page 0 addressing. */
2120 if (match
&& poss_indirect
)
2122 op_indirect
= opcode
;
2129 /* Page 0 addressing is used but not supported by any insn.
2130 If absolute addresses are supported, we use that insn. */
2131 if (match
== 0 && op_indirect
)
2133 opcode
= op_indirect
;
2145 /* Find the real opcode and its associated operands. We use a progressive
2146 approach here. On entry, 'opc' points to the first opcode in the
2147 table that matches the opcode name in the source line. We try to
2148 isolate an operand, find a possible match in the opcode table.
2149 We isolate another operand if no match were found. The table 'operands'
2150 is filled while operands are recognized.
2152 Returns the opcode pointer that matches the opcode name in the
2153 source line and the associated operands. */
2154 static struct m68hc11_opcode
*
2155 find_opcode (opc
, operands
, nb_operands
)
2156 struct m68hc11_opcode_def
*opc
;
2160 struct m68hc11_opcode
*opcode
;
2163 if (opc
->max_operands
== 0)
2169 for (i
= 0; i
< opc
->max_operands
;)
2173 result
= get_operand (&operands
[i
], i
, opc
->format
);
2177 /* Special case where the bitmask of the bclr/brclr
2178 instructions is not introduced by #.
2179 Example: bclr 3,x $80. */
2180 if (i
== 1 && (opc
->format
& M6811_OP_BITMASK
)
2181 && (operands
[i
].mode
& M6811_OP_IND16
))
2183 operands
[i
].mode
= M6811_OP_IMM16
;
2188 if (i
>= opc
->min_operands
)
2190 opcode
= find (opc
, operands
, i
);
2195 if (*input_line_pointer
== ',')
2196 input_line_pointer
++;
2202 #define M6812_XBCC_MARKER (M6812_OP_TBCC_MARKER \
2203 | M6812_OP_DBCC_MARKER \
2204 | M6812_OP_IBCC_MARKER)
2206 /* Gas line assembler entry point. */
2208 /* This is the main entry point for the machine-dependent assembler. str
2209 points to a machine-dependent instruction. This function is supposed to
2210 emit the frags/bytes it assembles to. */
2215 struct m68hc11_opcode_def
*opc
;
2216 struct m68hc11_opcode
*opcode
;
2218 unsigned char *op_start
, *save
;
2219 unsigned char *op_end
;
2222 operand operands
[M6811_MAX_OPERANDS
];
2224 int branch_optimize
= 0;
2227 /* Drop leading whitespace. */
2231 /* Find the opcode end and get the opcode in 'name'. The opcode is forced
2232 lower case (the opcode table only has lower case op-codes). */
2233 for (op_start
= op_end
= (unsigned char *) (str
);
2234 *op_end
&& nlen
< 20 && !is_end_of_line
[*op_end
] && *op_end
!= ' ';
2237 name
[nlen
] = tolower (op_start
[nlen
]);
2244 as_bad (_("No instruction or missing opcode."));
2248 /* Find the opcode definition given its name. */
2249 opc
= (struct m68hc11_opcode_def
*) hash_find (m68hc11_hash
, name
);
2251 /* If it's not recognized, look for 'jbsr' and 'jbxx'. These are
2252 pseudo insns for relative branch. For these branchs, we always
2253 optimize them (turned into absolute branchs) even if --short-branchs
2255 if (opc
== NULL
&& name
[0] == 'j' && name
[1] == 'b')
2257 opc
= (struct m68hc11_opcode_def
*) hash_find (m68hc11_hash
, &name
[1]);
2259 && (!(opc
->format
& M6811_OP_JUMP_REL
)
2260 || (opc
->format
& M6811_OP_BITMASK
)))
2263 branch_optimize
= 1;
2266 /* The following test should probably be removed. This is not conform
2267 to Motorola assembler specs. */
2268 if (opc
== NULL
&& flag_mri
)
2270 if (*op_end
== ' ' || *op_end
== '\t')
2272 while (*op_end
== ' ' || *op_end
== '\t')
2277 (is_end_of_line
[op_end
[1]]
2278 || op_end
[1] == ' ' || op_end
[1] == '\t'
2279 || !isalnum (op_end
[1])))
2280 && (*op_end
== 'a' || *op_end
== 'b'
2281 || *op_end
== 'A' || *op_end
== 'B'
2282 || *op_end
== 'd' || *op_end
== 'D'
2283 || *op_end
== 'x' || *op_end
== 'X'
2284 || *op_end
== 'y' || *op_end
== 'Y'))
2286 name
[nlen
++] = tolower (*op_end
++);
2288 opc
= (struct m68hc11_opcode_def
*) hash_find (m68hc11_hash
,
2294 /* Identify a possible instruction alias. There are some on the
2295 68HC12 to emulate a few 68HC11 instructions. */
2296 if (opc
== NULL
&& (current_architecture
& cpu6812
))
2300 for (i
= 0; i
< m68hc12_num_alias
; i
++)
2301 if (strcmp (m68hc12_alias
[i
].name
, name
) == 0)
2307 if (opc
== NULL
&& alias_id
< 0)
2309 as_bad (_("Opcode `%s' is not recognized."), name
);
2312 save
= input_line_pointer
;
2313 input_line_pointer
= op_end
;
2318 opcode
= find_opcode (opc
, operands
, &nb_operands
);
2323 if ((opcode
|| alias_id
>= 0) && !flag_mri
)
2325 char *p
= input_line_pointer
;
2327 while (*p
== ' ' || *p
== '\t' || *p
== '\n' || *p
== '\r')
2330 if (*p
!= '\n' && *p
)
2331 as_bad (_("Garbage at end of instruction: `%s'."), p
);
2334 input_line_pointer
= save
;
2338 char *f
= m68hc11_new_insn (m68hc12_alias
[alias_id
].size
);
2340 number_to_chars_bigendian (f
, m68hc12_alias
[alias_id
].code1
, 1);
2341 if (m68hc12_alias
[alias_id
].size
> 1)
2342 number_to_chars_bigendian (f
+ 1, m68hc12_alias
[alias_id
].code2
, 1);
2347 /* Opcode is known but does not have valid operands. Print out the
2348 syntax for this opcode. */
2351 if (flag_print_insn_syntax
)
2352 print_insn_format (name
);
2354 as_bad (_("Invalid operand for `%s'"), name
);
2358 /* Treat dbeq/ibeq/tbeq instructions in a special way. The branch is
2359 relative and must be in the range -256..255 (9-bits). */
2360 if ((opcode
->format
& M6812_XBCC_MARKER
)
2361 && (opcode
->format
& M6811_OP_JUMP_REL
))
2362 build_dbranch_insn (opcode
, operands
, nb_operands
);
2364 /* Relative jumps instructions are taken care of separately. We have to make
2365 sure that the relative branch is within the range -128..127. If it's out
2366 of range, the instructions are changed into absolute instructions.
2367 This is not supported for the brset and brclr instructions. */
2368 else if ((opcode
->format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
2369 && !(opcode
->format
& M6811_OP_BITMASK
))
2370 build_jump_insn (opcode
, operands
, nb_operands
, branch_optimize
);
2372 build_insn (opcode
, operands
, nb_operands
);
2375 /* Relocation, relaxation and frag conversions. */
2377 md_pcrel_from_section (fixp
, sec
)
2382 if (fixp
->fx_addsy
!= (symbolS
*) NULL
2383 && (!S_IS_DEFINED (fixp
->fx_addsy
)
2384 || (S_GET_SEGMENT (fixp
->fx_addsy
) != sec
)))
2387 adjust
= fixp
->fx_pcrel_adjust
;
2388 return fixp
->fx_frag
->fr_address
+ fixp
->fx_where
+ adjust
;
2391 /* If while processing a fixup, a reloc really needs to be created
2392 then it is done here. */
2394 tc_gen_reloc (section
, fixp
)
2400 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
2401 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
2402 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
2403 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
2404 if (fixp
->fx_r_type
== 0)
2405 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_16
);
2407 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
2408 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
2410 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2411 _("Relocation %d is not supported by object file format."),
2412 (int) fixp
->fx_r_type
);
2416 if (!fixp
->fx_pcrel
)
2417 reloc
->addend
= fixp
->fx_addnumber
;
2419 reloc
->addend
= (section
->vma
2420 + (fixp
->fx_pcrel_adjust
== 64
2421 ? -1 : fixp
->fx_pcrel_adjust
)
2422 + fixp
->fx_addnumber
2423 + md_pcrel_from_section (fixp
, section
));
2428 md_convert_frag (abfd
, sec
, fragP
)
2429 bfd
*abfd ATTRIBUTE_UNUSED
;
2430 asection
*sec ATTRIBUTE_UNUSED
;
2436 char *buffer_address
= fragP
->fr_literal
;
2438 /* Address in object code of the displacement. */
2439 register int object_address
= fragP
->fr_fix
+ fragP
->fr_address
;
2441 buffer_address
+= fragP
->fr_fix
;
2443 /* The displacement of the address, from current location. */
2444 value
= S_GET_VALUE (fragP
->fr_symbol
);
2445 disp
= (value
+ fragP
->fr_offset
) - object_address
;
2447 switch (fragP
->fr_subtype
)
2449 case ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_BYTE
):
2450 fragP
->fr_opcode
[1] = disp
;
2453 case ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_WORD
):
2454 /* This relax is only for bsr and bra. */
2455 assert (IS_OPCODE (fragP
->fr_opcode
[0], M6811_BSR
)
2456 || IS_OPCODE (fragP
->fr_opcode
[0], M6811_BRA
)
2457 || IS_OPCODE (fragP
->fr_opcode
[0], M6812_BSR
));
2459 fragP
->fr_opcode
[0] = convert_branch (fragP
->fr_opcode
[0]);
2461 fix_new (fragP
, fragP
->fr_fix
- 1, 2,
2462 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_16
);
2466 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
, STATE_BYTE
):
2467 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
, STATE_BYTE
):
2468 fragP
->fr_opcode
[1] = disp
;
2471 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
, STATE_WORD
):
2472 /* Invert branch. */
2473 fragP
->fr_opcode
[0] ^= 1;
2474 fragP
->fr_opcode
[1] = 3; /* Branch offset. */
2475 buffer_address
[0] = M6811_JMP
;
2476 fix_new (fragP
, fragP
->fr_fix
+ 1, 2,
2477 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_16
);
2481 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
, STATE_WORD
):
2482 /* Translate branch into a long branch. */
2483 fragP
->fr_opcode
[1] = fragP
->fr_opcode
[0];
2484 fragP
->fr_opcode
[0] = M6811_OPCODE_PAGE2
;
2486 fixp
= fix_new (fragP
, fragP
->fr_fix
, 2,
2487 fragP
->fr_symbol
, fragP
->fr_offset
, 1,
2488 BFD_RELOC_16_PCREL
);
2489 fixp
->fx_pcrel_adjust
= 2;
2493 case ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS5
):
2494 fragP
->fr_opcode
[0] = fragP
->fr_opcode
[0] << 6;
2495 if ((fragP
->fr_opcode
[0] & 0x0ff) == 0x0c0)
2496 fragP
->fr_opcode
[0] |= disp
& 0x1f;
2498 fragP
->fr_opcode
[0] |= value
& 0x1f;
2501 case ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS9
):
2502 fragP
->fr_opcode
[0] = (fragP
->fr_opcode
[0] << 3);
2503 fragP
->fr_opcode
[0] |= 0xE0;
2504 fix_new (fragP
, fragP
->fr_fix
, 1,
2505 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_8
);
2509 case ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS16
):
2510 fragP
->fr_opcode
[0] = (fragP
->fr_opcode
[0] << 3);
2511 fragP
->fr_opcode
[0] |= 0xe2;
2512 if ((fragP
->fr_opcode
[0] & 0x0ff) == 0x0fa)
2514 fixp
= fix_new (fragP
, fragP
->fr_fix
, 2,
2515 fragP
->fr_symbol
, fragP
->fr_offset
,
2516 1, BFD_RELOC_16_PCREL
);
2517 fixp
->fx_pcrel_adjust
= 2;
2521 fix_new (fragP
, fragP
->fr_fix
, 2,
2522 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_16
);
2527 case ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_BYTE
):
2529 fragP
->fr_opcode
[0] |= 0x10;
2531 fragP
->fr_opcode
[1] = disp
& 0x0FF;
2534 case ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_WORD
):
2535 /* Invert branch. */
2536 fragP
->fr_opcode
[0] ^= 0x20;
2537 fragP
->fr_opcode
[1] = 3; /* Branch offset. */
2538 buffer_address
[0] = M6812_JMP
;
2539 fix_new (fragP
, fragP
->fr_fix
+ 1, 2,
2540 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_16
);
2549 /* On an ELF system, we can't relax a weak symbol. The weak symbol
2550 can be overridden at final link time by a non weak symbol. We can
2551 relax externally visible symbol because there is no shared library
2552 and such symbol can't be overridden (unless they are weak). */
2554 relaxable_symbol (symbol
)
2557 return ! S_IS_WEAK (symbol
);
2560 /* Force truly undefined symbols to their maximum size, and generally set up
2561 the frag list to be relaxed. */
2563 md_estimate_size_before_relax (fragP
, segment
)
2567 if (RELAX_LENGTH (fragP
->fr_subtype
) == STATE_UNDF
)
2569 if (S_GET_SEGMENT (fragP
->fr_symbol
) != segment
2570 || !relaxable_symbol (fragP
->fr_symbol
))
2572 /* Non-relaxable cases. */
2574 char *buffer_address
;
2576 old_fr_fix
= fragP
->fr_fix
;
2577 buffer_address
= fragP
->fr_fix
+ fragP
->fr_literal
;
2579 switch (RELAX_STATE (fragP
->fr_subtype
))
2581 case STATE_PC_RELATIVE
:
2583 /* This relax is only for bsr and bra. */
2584 assert (IS_OPCODE (fragP
->fr_opcode
[0], M6811_BSR
)
2585 || IS_OPCODE (fragP
->fr_opcode
[0], M6811_BRA
)
2586 || IS_OPCODE (fragP
->fr_opcode
[0], M6812_BSR
));
2588 if (flag_fixed_branchs
)
2589 as_bad_where (fragP
->fr_file
, fragP
->fr_line
,
2590 _("bra or bsr with undefined symbol."));
2592 /* The symbol is undefined or in a separate section.
2593 Turn bra into a jmp and bsr into a jsr. The insn
2594 becomes 3 bytes long (instead of 2). A fixup is
2595 necessary for the unresolved symbol address. */
2596 fragP
->fr_opcode
[0] = convert_branch (fragP
->fr_opcode
[0]);
2599 fix_new (fragP
, old_fr_fix
- 1, 2, fragP
->fr_symbol
,
2600 fragP
->fr_offset
, 0, BFD_RELOC_16
);
2603 case STATE_CONDITIONAL_BRANCH
:
2604 assert (current_architecture
& cpu6811
);
2606 fragP
->fr_opcode
[0] ^= 1; /* Reverse sense of branch. */
2607 fragP
->fr_opcode
[1] = 3; /* Skip next jmp insn (3 bytes). */
2609 /* Don't use fr_opcode[2] because this may be
2610 in a different frag. */
2611 buffer_address
[0] = M6811_JMP
;
2614 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
2615 fragP
->fr_offset
, 0, BFD_RELOC_16
);
2619 case STATE_INDEXED_OFFSET
:
2620 assert (current_architecture
& cpu6812
);
2622 /* Switch the indexed operation to 16-bit mode. */
2623 fragP
->fr_opcode
[0] = fragP
->fr_opcode
[0] << 3;
2624 fragP
->fr_opcode
[0] |= 0xe2;
2626 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
2627 fragP
->fr_offset
, 0, BFD_RELOC_16
);
2631 case STATE_XBCC_BRANCH
:
2632 assert (current_architecture
& cpu6812
);
2634 fragP
->fr_opcode
[0] ^= 0x20; /* Reverse sense of branch. */
2635 fragP
->fr_opcode
[1] = 3; /* Skip next jmp insn (3 bytes). */
2637 /* Don't use fr_opcode[2] because this may be
2638 in a different frag. */
2639 buffer_address
[0] = M6812_JMP
;
2642 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
2643 fragP
->fr_offset
, 0, BFD_RELOC_16
);
2647 case STATE_CONDITIONAL_BRANCH_6812
:
2648 assert (current_architecture
& cpu6812
);
2650 /* Translate into a lbcc branch. */
2651 fragP
->fr_opcode
[1] = fragP
->fr_opcode
[0];
2652 fragP
->fr_opcode
[0] = M6811_OPCODE_PAGE2
;
2654 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
2655 fragP
->fr_offset
, 0, BFD_RELOC_16_PCREL
);
2660 as_fatal (_("Subtype %d is not recognized."), fragP
->fr_subtype
);
2664 /* Return the growth in the fixed part of the frag. */
2665 return fragP
->fr_fix
- old_fr_fix
;
2668 /* Relaxable cases. */
2669 switch (RELAX_STATE (fragP
->fr_subtype
))
2671 case STATE_PC_RELATIVE
:
2672 /* This relax is only for bsr and bra. */
2673 assert (IS_OPCODE (fragP
->fr_opcode
[0], M6811_BSR
)
2674 || IS_OPCODE (fragP
->fr_opcode
[0], M6811_BRA
)
2675 || IS_OPCODE (fragP
->fr_opcode
[0], M6812_BSR
));
2677 fragP
->fr_subtype
= ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_BYTE
);
2680 case STATE_CONDITIONAL_BRANCH
:
2681 assert (current_architecture
& cpu6811
);
2683 fragP
->fr_subtype
= ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
,
2687 case STATE_INDEXED_OFFSET
:
2688 assert (current_architecture
& cpu6812
);
2690 fragP
->fr_subtype
= ENCODE_RELAX (STATE_INDEXED_OFFSET
,
2694 case STATE_XBCC_BRANCH
:
2695 assert (current_architecture
& cpu6812
);
2697 fragP
->fr_subtype
= ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_BYTE
);
2700 case STATE_CONDITIONAL_BRANCH_6812
:
2701 assert (current_architecture
& cpu6812
);
2703 fragP
->fr_subtype
= ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
,
2709 if (fragP
->fr_subtype
>= sizeof (md_relax_table
) / sizeof (md_relax_table
[0]))
2710 as_fatal (_("Subtype %d is not recognized."), fragP
->fr_subtype
);
2712 /* Return the size of the variable part of the frag. */
2713 return md_relax_table
[fragP
->fr_subtype
].rlx_length
;
2717 md_apply_fix (fixp
, valuep
)
2725 if (fixp
->fx_addsy
== (symbolS
*) NULL
)
2730 else if (fixp
->fx_pcrel
)
2736 value
= fixp
->fx_offset
;
2737 if (fixp
->fx_subsy
!= (symbolS
*) NULL
)
2739 if (S_GET_SEGMENT (fixp
->fx_subsy
) == absolute_section
)
2741 value
-= S_GET_VALUE (fixp
->fx_subsy
);
2745 /* We don't actually support subtracting a symbol. */
2746 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2747 _("Expression too complex."));
2752 op_type
= fixp
->fx_r_type
;
2754 /* Patch the instruction with the resolved operand. Elf relocation
2755 info will also be generated to take care of linker/loader fixups.
2756 The 68HC11 addresses only 64Kb, we are only concerned by 8 and 16-bit
2757 relocs. BFD_RELOC_8 is basically used for .page0 access (the linker
2758 will warn for overflows). BFD_RELOC_8_PCREL should not be generated
2759 because it's either resolved or turned out into non-relative insns (see
2760 relax table, bcc, bra, bsr transformations)
2762 The BFD_RELOC_32 is necessary for the support of --gstabs. */
2763 where
= fixp
->fx_frag
->fr_literal
+ fixp
->fx_where
;
2765 switch (fixp
->fx_r_type
)
2768 bfd_putb32 ((bfd_vma
) value
, (unsigned char *) where
);
2772 case BFD_RELOC_16_PCREL
:
2773 bfd_putb16 ((bfd_vma
) value
, (unsigned char *) where
);
2774 if (value
< -65537 || value
> 65535)
2775 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2776 _("Value out of 16-bit range."));
2779 case BFD_RELOC_M68HC11_HI8
:
2783 case BFD_RELOC_M68HC11_LO8
:
2786 bfd_putb8 ((bfd_vma
) value
, (unsigned char *) where
);
2788 ((bfd_byte
*) where
)[0] = (bfd_byte
) value
;
2791 case BFD_RELOC_8_PCREL
:
2793 bfd_putb8 ((bfd_vma
) value
, (unsigned char *) where
);
2795 ((bfd_byte
*) where
)[0] = (bfd_byte
) value
;
2797 if (value
< -128 || value
> 127)
2798 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2799 _("Value %ld too large for 8-bit PC-relative branch."),
2803 case BFD_RELOC_M68HC11_3B
:
2804 if (value
<= 0 || value
> 8)
2805 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2806 _("Auto increment/decrement offset '%ld' is out of range."),
2813 where
[0] = where
[0] | (value
& 0x07);
2817 as_fatal (_("Line %d: unknown relocation type: 0x%x."),
2818 fixp
->fx_line
, fixp
->fx_r_type
);