1 /* tc-m68hc11.c -- Assembler code for the Motorola 68HC11 & 68HC12.
2 Copyright (C) 1999, 2000, 2001 Free Software Foundation.
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))
53 #define IS_OPCODE(C1,C2) (((C1) & 0x0FF) == ((C2) & 0x0FF))
55 /* This table describes how you change sizes for the various types of variable
56 size expressions. This version only supports two kinds. */
59 How far Forward this mode will reach.
60 How far Backward this mode will reach.
61 How many bytes this mode will add to the size of the frag.
62 Which mode to go to if the offset won't fit in this one. */
64 relax_typeS md_relax_table
[] = {
65 {1, 1, 0, 0}, /* First entries aren't used. */
66 {1, 1, 0, 0}, /* For no good reason except. */
67 {1, 1, 0, 0}, /* that the VAX doesn't either. */
71 These insns are translated into b!cc +3 jmp L. */
72 {(127), (-128), 0, ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
, STATE_WORD
)},
77 /* Relax for bsr <L> and bra <L>.
78 These insns are translated into jsr and jmp. */
79 {(127), (-128), 0, ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_WORD
)},
84 /* Relax for indexed offset: 5-bits, 9-bits, 16-bits. */
85 {(15), (-16), 0, ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS9
)},
86 {(255), (-256), 1, ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS16
)},
90 /* Relax for dbeq/ibeq/tbeq r,<L>:
91 These insns are translated into db!cc +3 jmp L. */
92 {(255), (-256), 0, ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_WORD
)},
97 /* Relax for bcc <L> on 68HC12.
98 These insns are translated into lbcc <L>. */
99 {(127), (-128), 0, ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
, STATE_WORD
)},
106 /* 68HC11 and 68HC12 registers. They are numbered according to the 68HC12. */
107 typedef enum register_id
{
119 typedef struct operand
{
126 struct m68hc11_opcode_def
{
132 struct m68hc11_opcode
*opcode
;
135 static struct m68hc11_opcode_def
*m68hc11_opcode_defs
= 0;
136 static int m68hc11_nb_opcode_defs
= 0;
138 typedef struct alias
{
143 static alias alias_opcodes
[] = {
150 /* Local functions. */
151 static register_id reg_name_search
PARAMS ((char *));
152 static register_id register_name
PARAMS ((void));
153 static int check_range
PARAMS ((long, int));
154 static void print_opcode_list
PARAMS ((void));
155 static void get_default_target
PARAMS ((void));
156 static void print_insn_format
PARAMS ((char *));
157 static int get_operand
PARAMS ((operand
*, int, long));
158 static void fixup8
PARAMS ((expressionS
*, int, int));
159 static void fixup16
PARAMS ((expressionS
*, int, int));
160 static struct m68hc11_opcode
*find_opcode
161 PARAMS ((struct m68hc11_opcode_def
*, operand
*, int *));
162 static void build_jump_insn
163 PARAMS ((struct m68hc11_opcode
*, operand
*, int, int));
164 static void build_insn
165 PARAMS ((struct m68hc11_opcode
*, operand
*, int));
167 /* Controls whether relative branches can be turned into long branches.
168 When the relative offset is too large, the insn are changed:
176 Setting the flag forbidds this. */
177 static short flag_fixed_branchs
= 0;
179 /* Force to use long jumps (absolute) instead of relative branches. */
180 static short flag_force_long_jumps
= 0;
182 /* Change the direct addressing mode into an absolute addressing mode
183 when the insn does not support direct addressing.
184 For example, "clr *ZD0" is normally not possible and is changed
186 static short flag_strict_direct_addressing
= 1;
188 /* When an opcode has invalid operand, print out the syntax of the opcode
190 static short flag_print_insn_syntax
= 0;
192 /* Dumps the list of instructions with syntax and then exit:
193 1 -> Only dumps the list (sorted by name)
194 2 -> Generate an example (or test) that can be compiled. */
195 static short flag_print_opcodes
= 0;
197 /* Opcode hash table. */
198 static struct hash_control
*m68hc11_hash
;
200 /* Current cpu (either cpu6811 or cpu6812). This is determined automagically
201 by 'get_default_target' by looking at default BFD vector. This is overriden
202 with the -m<cpu> option. */
203 static int current_architecture
= 0;
205 /* Default cpu determined by 'get_default_target'. */
206 static const char *default_cpu
;
208 /* Number of opcodes in the sorted table (filtered by current cpu). */
209 static int num_opcodes
;
211 /* The opcodes sorted by name and filtered by current cpu. */
212 static struct m68hc11_opcode
*m68hc11_sorted_opcodes
;
214 /* These are the machine dependent pseudo-ops. These are included so
215 the assembler can work on the output from the SUN C compiler, which
218 /* This table describes all the machine specific pseudo-ops the assembler
219 has to support. The fields are:
220 pseudo-op name without dot
221 function to call to execute this pseudo-op
222 Integer arg to pass to the function. */
223 const pseudo_typeS md_pseudo_table
[] = {
224 /* The following pseudo-ops are supported for MRI compatibility. */
227 {"fcc", stringer
, 1},
229 {"file", dwarf2_directive_file
, 0},
230 {"loc", dwarf2_directive_loc
, 0},
235 /* Options and initialization. */
237 CONST
char *md_shortopts
= "Sm:";
239 struct option md_longopts
[] = {
240 #define OPTION_FORCE_LONG_BRANCH (OPTION_MD_BASE)
241 {"force-long-branchs", no_argument
, NULL
, OPTION_FORCE_LONG_BRANCH
},
243 #define OPTION_SHORT_BRANCHS (OPTION_MD_BASE + 1)
244 {"short-branchs", no_argument
, NULL
, OPTION_SHORT_BRANCHS
},
246 #define OPTION_STRICT_DIRECT_MODE (OPTION_MD_BASE + 2)
247 {"strict-direct-mode", no_argument
, NULL
, OPTION_STRICT_DIRECT_MODE
},
249 #define OPTION_PRINT_INSN_SYNTAX (OPTION_MD_BASE + 3)
250 {"print-insn-syntax", no_argument
, NULL
, OPTION_PRINT_INSN_SYNTAX
},
252 #define OPTION_PRINT_OPCODES (OPTION_MD_BASE + 4)
253 {"print-opcodes", no_argument
, NULL
, OPTION_PRINT_OPCODES
},
255 #define OPTION_GENERATE_EXAMPLE (OPTION_MD_BASE + 5)
256 {"generate-example", no_argument
, NULL
, OPTION_GENERATE_EXAMPLE
},
258 {NULL
, no_argument
, NULL
, 0}
260 size_t md_longopts_size
= sizeof (md_longopts
);
262 /* Get the target cpu for the assembler. This is based on the configure
263 options and on the -m68hc11/-m68hc12 option. If no option is specified,
264 we must get the default. */
266 m68hc11_arch_format ()
268 get_default_target ();
269 if (current_architecture
& cpu6811
)
270 return "elf32-m68hc11";
272 return "elf32-m68hc12";
275 enum bfd_architecture
278 get_default_target ();
279 if (current_architecture
& cpu6811
)
280 return bfd_arch_m68hc11
;
282 return bfd_arch_m68hc12
;
292 md_show_usage (stream
)
295 get_default_target ();
296 fprintf (stream
, _("\
297 Motorola 68HC11/68HC12 options:\n\
298 -m68hc11 | -m68hc12 specify the processor [default %s]\n\
299 --force-long-branchs always turn relative branchs into absolute ones\n\
300 -S,--short-branchs do not turn relative branchs into absolute ones\n\
301 when the offset is out of range\n\
302 --strict-direct-mode do not turn the direct mode into extended mode\n\
303 when the instruction does not support direct mode\n\
304 --print-insn-syntax print the syntax of instruction in case of error\n\
305 --print-opcodes print the list of instructions with syntax\n\
306 --generate-example generate an example of each instruction\n\
307 (used for testing)\n"), default_cpu
);
311 /* Try to identify the default target based on the BFD library. */
313 get_default_target ()
315 const bfd_target
*target
;
318 if (current_architecture
!= 0)
321 default_cpu
= "unknown";
322 target
= bfd_find_target (0, &abfd
);
323 if (target
&& target
->name
)
325 if (strcmp (target
->name
, "elf32-m68hc12") == 0)
327 current_architecture
= cpu6812
;
328 default_cpu
= "m68hc12";
330 else if (strcmp (target
->name
, "elf32-m68hc11") == 0)
332 current_architecture
= cpu6811
;
333 default_cpu
= "m68hc11";
337 as_bad (_("Default target `%s' is not supported."), target
->name
);
343 m68hc11_print_statistics (file
)
347 struct m68hc11_opcode_def
*opc
;
349 hash_print_statistics (file
, "opcode table", m68hc11_hash
);
351 opc
= m68hc11_opcode_defs
;
352 if (opc
== 0 || m68hc11_nb_opcode_defs
== 0)
355 /* Dump the opcode statistics table. */
356 fprintf (file
, _("Name # Modes Min ops Max ops Modes mask # Used\n"));
357 for (i
= 0; i
< m68hc11_nb_opcode_defs
; i
++, opc
++)
359 fprintf (file
, "%-7.7s %5d %7d %7d 0x%08lx %7d\n",
362 opc
->min_operands
, opc
->max_operands
, opc
->format
, opc
->used
);
367 md_parse_option (c
, arg
)
371 get_default_target ();
374 /* -S means keep external to 2 bits offset rather than 16 bits one. */
375 case OPTION_SHORT_BRANCHS
:
377 flag_fixed_branchs
= 1;
380 case OPTION_FORCE_LONG_BRANCH
:
381 flag_force_long_jumps
= 1;
384 case OPTION_PRINT_INSN_SYNTAX
:
385 flag_print_insn_syntax
= 1;
388 case OPTION_PRINT_OPCODES
:
389 flag_print_opcodes
= 1;
392 case OPTION_STRICT_DIRECT_MODE
:
393 flag_strict_direct_addressing
= 0;
396 case OPTION_GENERATE_EXAMPLE
:
397 flag_print_opcodes
= 2;
401 if (strcasecmp (arg
, "68hc11") == 0)
402 current_architecture
= cpu6811
;
403 else if (strcasecmp (arg
, "68hc12") == 0)
404 current_architecture
= cpu6812
;
406 as_bad (_("Option `%s' is not recognized."), arg
);
417 md_undefined_symbol (name
)
418 char *name ATTRIBUTE_UNUSED
;
423 /* Equal to MAX_PRECISION in atof-ieee.c. */
424 #define MAX_LITTLENUMS 6
426 /* Turn a string in input_line_pointer into a floating point constant
427 of type TYPE, and store the appropriate bytes in *LITP. The number
428 of LITTLENUMS emitted is stored in *SIZEP. An error message is
429 returned, or NULL on OK. */
431 md_atof (type
, litP
, sizeP
)
437 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
438 LITTLENUM_TYPE
*wordP
;
469 return _("Bad call to MD_ATOF()");
471 t
= atof_ieee (input_line_pointer
, type
, words
);
473 input_line_pointer
= t
;
475 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
476 for (wordP
= words
; prec
--;)
478 md_number_to_chars (litP
, (long) (*wordP
++), sizeof (LITTLENUM_TYPE
));
479 litP
+= sizeof (LITTLENUM_TYPE
);
485 md_section_align (seg
, addr
)
489 int align
= bfd_get_section_alignment (stdoutput
, seg
);
490 return ((addr
+ (1 << align
) - 1) & (-1 << align
));
494 cmp_opcode (op1
, op2
)
495 struct m68hc11_opcode
*op1
;
496 struct m68hc11_opcode
*op2
;
498 return strcmp (op1
->name
, op2
->name
);
501 /* Initialize the assembler. Create the opcode hash table
502 (sorted on the names) with the M6811 opcode table
503 (from opcode library). */
507 char *prev_name
= "";
508 struct m68hc11_opcode
*opcodes
;
509 struct m68hc11_opcode_def
*opc
= 0;
512 get_default_target ();
514 m68hc11_hash
= hash_new ();
516 /* Get a writable copy of the opcode table and sort it on the names. */
517 opcodes
= (struct m68hc11_opcode
*) xmalloc (m68hc11_num_opcodes
*
520 m68hc11_sorted_opcodes
= opcodes
;
522 for (i
= 0; i
< m68hc11_num_opcodes
; i
++)
524 if (m68hc11_opcodes
[i
].arch
& current_architecture
)
526 opcodes
[num_opcodes
] = m68hc11_opcodes
[i
];
527 if (opcodes
[num_opcodes
].name
[0] == 'b'
528 && opcodes
[num_opcodes
].format
& M6811_OP_JUMP_REL
529 && !(opcodes
[num_opcodes
].format
& M6811_OP_BITMASK
))
532 opcodes
[num_opcodes
] = m68hc11_opcodes
[i
];
535 for (j
= 0; alias_opcodes
[j
].name
!= 0; j
++)
536 if (strcmp (m68hc11_opcodes
[i
].name
, alias_opcodes
[j
].name
) == 0)
538 opcodes
[num_opcodes
] = m68hc11_opcodes
[i
];
539 opcodes
[num_opcodes
].name
= alias_opcodes
[j
].alias
;
545 qsort (opcodes
, num_opcodes
, sizeof (struct m68hc11_opcode
), cmp_opcode
);
547 opc
= (struct m68hc11_opcode_def
*)
548 xmalloc (num_opcodes
* sizeof (struct m68hc11_opcode_def
));
549 m68hc11_opcode_defs
= opc
--;
551 /* Insert unique names into hash table. The M6811 instruction set
552 has several identical opcode names that have different opcodes based
553 on the operands. This hash table then provides a quick index to
554 the first opcode with a particular name in the opcode table. */
555 for (i
= 0; i
< num_opcodes
; i
++, opcodes
++)
559 if (strcmp (prev_name
, opcodes
->name
))
561 prev_name
= (char *) opcodes
->name
;
565 opc
->min_operands
= 100;
566 opc
->max_operands
= 0;
568 opc
->opcode
= opcodes
;
570 hash_insert (m68hc11_hash
, opcodes
->name
, (char *) opc
);
573 opc
->format
|= opcodes
->format
;
575 /* See how many operands this opcode needs. */
577 if (opcodes
->format
& M6811_OP_MASK
)
579 if (opcodes
->format
& M6811_OP_BITMASK
)
581 if (opcodes
->format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
583 if (opcodes
->format
& (M6812_OP_IND16_P2
| M6812_OP_IDX_P2
))
586 if (expect
< opc
->min_operands
)
587 opc
->min_operands
= expect
;
588 if (expect
> opc
->max_operands
)
589 opc
->max_operands
= expect
;
592 m68hc11_nb_opcode_defs
= opc
- m68hc11_opcode_defs
;
594 if (flag_print_opcodes
)
596 print_opcode_list ();
602 m68hc11_init_after_args ()
608 /* Return a string that represents the operand format for the instruction.
609 When example is true, this generates an example of operand. This is used
610 to give an example and also to generate a test. */
612 print_opcode_format (opcode
, example
)
613 struct m68hc11_opcode
*opcode
;
616 static char buf
[128];
617 int format
= opcode
->format
;
622 if (format
& M6811_OP_IMM8
)
625 sprintf (p
, "#%d", rand () & 0x0FF);
627 strcpy (p
, _("#<imm8>"));
631 if (format
& M6811_OP_IMM16
)
634 sprintf (p
, "#%d", rand () & 0x0FFFF);
636 strcpy (p
, _("#<imm16>"));
640 if (format
& M6811_OP_IX
)
643 sprintf (p
, "%d,X", rand () & 0x0FF);
645 strcpy (p
, _("<imm8>,X"));
649 if (format
& M6811_OP_IY
)
652 sprintf (p
, "%d,X", rand () & 0x0FF);
654 strcpy (p
, _("<imm8>,X"));
658 if (format
& M6812_OP_IDX
)
661 sprintf (p
, "%d,X", rand () & 0x0FF);
667 if (format
& M6811_OP_DIRECT
)
670 sprintf (p
, "*Z%d", rand () & 0x0FF);
672 strcpy (p
, _("*<abs8>"));
676 if (format
& M6811_OP_BITMASK
)
682 sprintf (p
, "#$%02x", rand () & 0x0FF);
684 strcpy (p
, _("#<mask>"));
687 if (format
& M6811_OP_JUMP_REL
)
691 if (format
& M6811_OP_IND16
)
694 sprintf (p
, _("symbol%d"), rand () & 0x0FF);
696 strcpy (p
, _("<abs>"));
701 if (format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
705 if (format
& M6811_OP_BITMASK
)
707 sprintf (p
, ".+%d", rand () & 0x7F);
711 sprintf (p
, "L%d", rand () & 0x0FF);
715 strcpy (p
, _("<label>"));
721 /* Prints the list of instructions with the possible operands. */
726 char *prev_name
= "";
727 struct m68hc11_opcode
*opcodes
;
728 int example
= flag_print_opcodes
== 2;
731 printf (_("# Example of `%s' instructions\n\t.sect .text\n_start:\n"),
734 opcodes
= m68hc11_sorted_opcodes
;
736 /* Walk the list sorted on names (by md_begin). We only report
737 one instruction per line, and we collect the different operand
739 for (i
= 0; i
< num_opcodes
; i
++, opcodes
++)
741 char *fmt
= print_opcode_format (opcodes
, example
);
745 printf ("L%d:\t", i
);
746 printf ("%s %s\n", opcodes
->name
, fmt
);
750 if (strcmp (prev_name
, opcodes
->name
))
755 printf ("%-5.5s ", opcodes
->name
);
756 prev_name
= (char *) opcodes
->name
;
759 printf (" [%s]", fmt
);
765 /* Print the instruction format. This operation is called when some
766 instruction is not correct. Instruction format is printed as an
769 print_insn_format (name
)
772 struct m68hc11_opcode_def
*opc
;
773 struct m68hc11_opcode
*opcode
;
776 opc
= (struct m68hc11_opcode_def
*) hash_find (m68hc11_hash
, name
);
779 as_bad (_("Instruction `%s' is not recognized."), name
);
782 opcode
= opc
->opcode
;
784 as_bad (_("Instruction formats for `%s':"), name
);
789 fmt
= print_opcode_format (opcode
, 0, 0);
790 sprintf (buf
, "\t%-5.5s %s", opcode
->name
, fmt
);
795 while (strcmp (opcode
->name
, name
) == 0);
798 /* Analysis of 68HC11 and 68HC12 operands. */
800 /* reg_name_search() finds the register number given its name.
801 Returns the register number or REG_NONE on failure. */
803 reg_name_search (name
)
806 if (strcasecmp (name
, "x") == 0 || strcasecmp (name
, "ix") == 0)
808 if (strcasecmp (name
, "y") == 0 || strcasecmp (name
, "iy") == 0)
810 if (strcasecmp (name
, "a") == 0)
812 if (strcasecmp (name
, "b") == 0)
814 if (strcasecmp (name
, "d") == 0)
816 if (strcasecmp (name
, "sp") == 0)
818 if (strcasecmp (name
, "pc") == 0)
820 if (strcasecmp (name
, "ccr") == 0)
830 while (*p
== ' ' || *p
== '\t')
836 /* Check the string at input_line_pointer
837 to see if it is a valid register name. */
841 register_id reg_number
;
842 char c
, *p
= input_line_pointer
;
844 if (!is_name_beginner (*p
++))
847 while (is_part_of_name (*p
++))
854 /* Look to see if it's in the register table. */
855 reg_number
= reg_name_search (input_line_pointer
);
856 if (reg_number
!= REG_NONE
)
861 input_line_pointer
= p
;
870 /* Parse a string of operands and return an array of expressions.
872 Operand mode[0] mode[1] exp[0] exp[1]
873 #n M6811_OP_IMM16 - O_*
874 *<exp> M6811_OP_DIRECT - O_*
875 .{+-}<exp> M6811_OP_JUMP_REL - O_*
876 <exp> M6811_OP_IND16 - O_*
877 ,r N,r M6812_OP_IDX M6812_OP_REG O_constant O_register
878 n,-r M6812_PRE_DEC M6812_OP_REG O_constant O_register
879 n,+r M6812_PRE_INC " "
880 n,r- M6812_POST_DEC " "
881 n,r+ M6812_POST_INC " "
882 A,r B,r D,r M6811_OP_REG M6812_OP_REG O_register O_register
883 [D,r] M6811_OP_IDX_2 M6812_OP_REG O_register O_register
884 [n,r] M6811_OP_IDX_1 M6812_OP_REG O_constant O_register */
886 get_operand (oper
, which
, opmode
)
891 char *p
= input_line_pointer
;
895 oper
->exp
.X_op
= O_absent
;
896 oper
->reg1
= REG_NONE
;
897 oper
->reg2
= REG_NONE
;
898 mode
= M6811_OP_NONE
;
902 if (*p
== 0 || *p
== '\n' || *p
== '\r')
904 input_line_pointer
= p
;
908 if (*p
== '*' && (opmode
& (M6811_OP_DIRECT
| M6811_OP_IND16
)))
910 mode
= M6811_OP_DIRECT
;
915 if (!(opmode
& (M6811_OP_IMM8
| M6811_OP_IMM16
| M6811_OP_BITMASK
)))
917 as_bad (_("Immediate operand is not allowed for operand %d."),
922 mode
= M6811_OP_IMM16
;
924 if (strncmp (p
, "%hi", 3) == 0)
927 mode
|= M6811_OP_HIGH_ADDR
;
929 else if (strncmp (p
, "%lo", 3) == 0)
932 mode
|= M6811_OP_LOW_ADDR
;
935 else if (*p
== '.' && (p
[1] == '+' || p
[1] == '-'))
938 mode
= M6811_OP_JUMP_REL
;
942 if (current_architecture
& cpu6811
)
943 as_bad (_("Indirect indexed addressing is not valid for 68HC11."));
946 mode
= M6812_OP_IDX_2
;
949 else if (*p
== ',') /* Special handling of ,x and ,y. */
952 input_line_pointer
= p
;
954 reg
= register_name ();
958 oper
->exp
.X_op
= O_constant
;
959 oper
->exp
.X_add_number
= 0;
960 oper
->mode
= M6812_OP_IDX
;
963 as_bad (_("Spurious `,' or bad indirect register addressing mode."));
966 input_line_pointer
= p
;
968 if (mode
== M6811_OP_NONE
|| mode
== M6812_OP_IDX_2
)
969 reg
= register_name ();
975 p
= skip_whites (input_line_pointer
);
976 if (*p
== ']' && mode
== M6812_OP_IDX_2
)
979 (_("Missing second register or offset for indexed-indirect mode."));
984 oper
->mode
= mode
| M6812_OP_REG
;
987 if (mode
== M6812_OP_IDX_2
)
989 as_bad (_("Missing second register for indexed-indirect mode."));
996 input_line_pointer
= p
;
997 reg
= register_name ();
1000 p
= skip_whites (input_line_pointer
);
1001 if (mode
== M6812_OP_IDX_2
)
1005 as_bad (_("Missing `]' to close indexed-indirect mode."));
1010 input_line_pointer
= p
;
1018 /* In MRI mode, isolate the operand because we can't distinguish
1019 operands from comments. */
1024 p
= skip_whites (p
);
1025 while (*p
&& *p
!= ' ' && *p
!= '\t')
1034 /* Parse as an expression. */
1035 expression (&oper
->exp
);
1044 expression (&oper
->exp
);
1047 if (oper
->exp
.X_op
== O_illegal
)
1049 as_bad (_("Illegal operand."));
1052 else if (oper
->exp
.X_op
== O_absent
)
1054 as_bad (_("Missing operand."));
1058 p
= input_line_pointer
;
1060 if (mode
== M6811_OP_NONE
|| mode
== M6811_OP_DIRECT
1061 || mode
== M6812_OP_IDX_2
)
1063 p
= skip_whites (input_line_pointer
);
1067 int possible_mode
= M6811_OP_NONE
;
1068 char *old_input_line
;
1071 /* 68HC12 pre increment or decrement. */
1072 if (mode
== M6811_OP_NONE
)
1076 possible_mode
= M6812_PRE_DEC
;
1081 possible_mode
= M6812_PRE_INC
;
1084 p
= skip_whites (p
);
1086 old_input_line
= input_line_pointer
;
1087 input_line_pointer
= p
;
1088 reg
= register_name ();
1090 /* Backtrack if we have a valid constant expression and
1091 it does not correspond to the offset of the 68HC12 indexed
1092 addressing mode (as in N,x). */
1093 if (reg
== REG_NONE
&& mode
== M6811_OP_NONE
1094 && possible_mode
!= M6811_OP_NONE
)
1096 oper
->mode
= M6811_OP_IND16
| M6811_OP_JUMP_REL
;
1097 input_line_pointer
= skip_whites (old_input_line
);
1101 if (possible_mode
!= M6811_OP_NONE
)
1102 mode
= possible_mode
;
1104 if ((current_architecture
& cpu6811
)
1105 && possible_mode
!= M6811_OP_NONE
)
1106 as_bad (_("Pre-increment mode is not valid for 68HC11"));
1108 if (which
== 0 && opmode
& M6812_OP_IDX_P2
1109 && reg
!= REG_X
&& reg
!= REG_Y
1110 && reg
!= REG_PC
&& reg
!= REG_SP
)
1113 input_line_pointer
= p
;
1116 if (reg
== REG_NONE
&& mode
!= M6811_OP_DIRECT
1117 && !(mode
== M6811_OP_NONE
&& opmode
& M6811_OP_IND16
))
1119 as_bad (_("Wrong register in register indirect mode."));
1122 if (mode
== M6812_OP_IDX_2
)
1124 p
= skip_whites (input_line_pointer
);
1127 as_bad (_("Missing `]' to close register indirect operand."));
1130 input_line_pointer
= p
;
1132 if (reg
!= REG_NONE
)
1135 if (mode
== M6811_OP_NONE
)
1137 p
= input_line_pointer
;
1140 mode
= M6812_POST_DEC
;
1142 if (current_architecture
& cpu6811
)
1144 (_("Post-decrement mode is not valid for 68HC11."));
1148 mode
= M6812_POST_INC
;
1150 if (current_architecture
& cpu6811
)
1152 (_("Post-increment mode is not valid for 68HC11."));
1155 mode
= M6812_OP_IDX
;
1157 input_line_pointer
= p
;
1160 mode
|= M6812_OP_IDX
;
1167 if (mode
== M6812_OP_D_IDX_2
)
1169 as_bad (_("Invalid indexed indirect mode."));
1174 /* If the mode is not known until now, this is either a label
1175 or an indirect address. */
1176 if (mode
== M6811_OP_NONE
)
1177 mode
= M6811_OP_IND16
| M6811_OP_JUMP_REL
;
1179 p
= input_line_pointer
;
1180 while (*p
== ' ' || *p
== '\t')
1182 input_line_pointer
= p
;
1188 #define M6812_AUTO_INC_DEC (M6812_PRE_INC | M6812_PRE_DEC \
1189 | M6812_POST_INC | M6812_POST_DEC)
1191 /* Checks that the number 'num' fits for a given mode. */
1193 check_range (num
, mode
)
1197 /* Auto increment and decrement are ok for [-8..8] without 0. */
1198 if (mode
& M6812_AUTO_INC_DEC
)
1199 return (num
!= 0 && num
<= 8 && num
>= -8);
1201 /* The 68HC12 supports 5, 9 and 16-bits offsets. */
1202 if (mode
& (M6812_INDEXED_IND
| M6812_INDEXED
| M6812_OP_IDX
))
1203 mode
= M6811_OP_IND16
;
1205 if (mode
& M6812_OP_JUMP_REL16
)
1206 mode
= M6811_OP_IND16
;
1212 case M6811_OP_DIRECT
:
1213 return (num
>= 0 && num
<= 255) ? 1 : 0;
1215 case M6811_OP_BITMASK
:
1217 return (((num
& 0xFFFFFF00) == 0) || ((num
& 0xFFFFFF00) == 0xFFFFFF00))
1220 case M6811_OP_JUMP_REL
:
1221 return (num
>= -128 && num
<= 127) ? 1 : 0;
1223 case M6811_OP_IND16
:
1224 case M6811_OP_IMM16
:
1225 return (((num
& 0xFFFF0000) == 0) || ((num
& 0xFFFF0000) == 0xFFFF0000))
1228 case M6812_OP_IBCC_MARKER
:
1229 case M6812_OP_TBCC_MARKER
:
1230 case M6812_OP_DBCC_MARKER
:
1231 return (num
>= -256 && num
<= 255) ? 1 : 0;
1233 case M6812_OP_TRAP_ID
:
1234 return ((num
>= 0x30 && num
<= 0x39)
1235 || (num
>= 0x40 && num
<= 0x0ff)) ? 1 : 0;
1242 /* Gas fixup generation. */
1244 /* Put a 1 byte expression described by 'oper'. If this expression contains
1245 unresolved symbols, generate an 8-bit fixup. */
1247 fixup8 (oper
, mode
, opmode
)
1256 if (oper
->X_op
== O_constant
)
1258 if (mode
& M6812_OP_TRAP_ID
1259 && !check_range (oper
->X_add_number
, M6812_OP_TRAP_ID
))
1261 static char trap_id_warn_once
= 0;
1263 as_bad (_("Trap id `%ld' is out of range."), oper
->X_add_number
);
1264 if (trap_id_warn_once
== 0)
1266 trap_id_warn_once
= 1;
1267 as_bad (_("Trap id must be within [0x30..0x39] or [0x40..0xff]."));
1271 if (!(mode
& M6812_OP_TRAP_ID
)
1272 && !check_range (oper
->X_add_number
, mode
))
1274 as_bad (_("Operand out of 8-bit range: `%ld'."), oper
->X_add_number
);
1276 number_to_chars_bigendian (f
, oper
->X_add_number
& 0x0FF, 1);
1278 else if (oper
->X_op
!= O_register
)
1280 if (mode
& M6812_OP_TRAP_ID
)
1281 as_bad (_("The trap id must be a constant."));
1283 if (mode
== M6811_OP_JUMP_REL
)
1287 fixp
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 1,
1288 oper
, true, BFD_RELOC_8_PCREL
);
1289 fixp
->fx_pcrel_adjust
= 1;
1293 /* Now create an 8-bit fixup. If there was some %hi or %lo
1294 modifier, generate the reloc accordingly. */
1295 fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 1,
1297 ((opmode
& M6811_OP_HIGH_ADDR
)
1298 ? BFD_RELOC_M68HC11_HI8
1299 : ((opmode
& M6811_OP_LOW_ADDR
)
1300 ? BFD_RELOC_M68HC11_LO8
: BFD_RELOC_8
)));
1302 number_to_chars_bigendian (f
, 0, 1);
1306 as_fatal (_("Operand `%x' not recognized in fixup8."), oper
->X_op
);
1310 /* Put a 2 bytes expression described by 'oper'. If this expression contains
1311 unresolved symbols, generate a 16-bit fixup. */
1313 fixup16 (oper
, mode
, opmode
)
1316 int opmode ATTRIBUTE_UNUSED
;
1322 if (oper
->X_op
== O_constant
)
1324 if (!check_range (oper
->X_add_number
, mode
))
1326 as_bad (_("Operand out of 16-bit range: `%ld'."),
1327 oper
->X_add_number
);
1329 number_to_chars_bigendian (f
, oper
->X_add_number
& 0x0FFFF, 2);
1331 else if (oper
->X_op
!= O_register
)
1335 /* Now create a 16-bit fixup. */
1336 fixp
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 2,
1338 (mode
& M6812_OP_JUMP_REL16
? true : false),
1339 (mode
& M6812_OP_JUMP_REL16
1340 ? BFD_RELOC_16_PCREL
: BFD_RELOC_16
));
1341 number_to_chars_bigendian (f
, 0, 2);
1342 if (mode
& M6812_OP_JUMP_REL16
)
1343 fixp
->fx_pcrel_adjust
= 2;
1347 as_fatal (_("Operand `%x' not recognized in fixup16."), oper
->X_op
);
1351 /* 68HC11 and 68HC12 code generation. */
1353 /* Translate the short branch/bsr instruction into a long branch. */
1354 static unsigned char
1355 convert_branch (code
)
1358 if (IS_OPCODE (code
, M6812_BSR
))
1360 else if (IS_OPCODE (code
, M6811_BSR
))
1362 else if (IS_OPCODE (code
, M6811_BRA
))
1363 return (current_architecture
& cpu6812
) ? M6812_JMP
: M6811_JMP
;
1365 as_fatal (_("Unexpected branch conversion with `%x'"), code
);
1367 /* Keep gcc happy. */
1371 /* Start a new insn that contains at least 'size' bytes. Record the
1372 line information of that insn in the dwarf2 debug sections. */
1374 m68hc11_new_insn (size
)
1379 f
= frag_more (size
);
1381 dwarf2_emit_insn (size
);
1386 /* Builds a jump instruction (bra, bcc, bsr). */
1388 build_jump_insn (opcode
, operands
, nb_operands
, jmp_mode
)
1389 struct m68hc11_opcode
*opcode
;
1399 /* The relative branch convertion is not supported for
1401 assert ((opcode
->format
& M6811_OP_BITMASK
) == 0);
1402 assert (nb_operands
== 1);
1403 assert (operands
[0].reg1
== REG_NONE
&& operands
[0].reg2
== REG_NONE
);
1405 code
= opcode
->opcode
;
1408 n
= operands
[0].exp
.X_add_number
;
1410 /* Turn into a long branch:
1411 - when force long branch option (and not for jbcc pseudos),
1412 - when jbcc and the constant is out of -128..127 range,
1413 - when branch optimization is allowed and branch out of range. */
1414 if ((jmp_mode
== 0 && flag_force_long_jumps
)
1415 || (operands
[0].exp
.X_op
== O_constant
1416 && (!check_range (n
, opcode
->format
) &&
1417 (jmp_mode
== 1 || flag_fixed_branchs
== 0))))
1419 if (code
== M6811_BSR
|| code
== M6811_BRA
|| code
== M6812_BSR
)
1421 code
= convert_branch (code
);
1423 f
= m68hc11_new_insn (1);
1424 number_to_chars_bigendian (f
, code
, 1);
1426 else if (current_architecture
& cpu6812
)
1428 /* 68HC12: translate the bcc into a lbcc. */
1429 f
= m68hc11_new_insn (2);
1430 number_to_chars_bigendian (f
, M6811_OPCODE_PAGE2
, 1);
1431 number_to_chars_bigendian (f
+ 1, code
, 1);
1432 fixup16 (&operands
[0].exp
, M6812_OP_JUMP_REL16
,
1433 M6812_OP_JUMP_REL16
);
1438 /* 68HC11: translate the bcc into b!cc +3; jmp <L>. */
1439 f
= m68hc11_new_insn (3);
1441 number_to_chars_bigendian (f
, code
, 1);
1442 number_to_chars_bigendian (f
+ 1, 3, 1);
1443 number_to_chars_bigendian (f
+ 2, M6811_JMP
, 1);
1445 fixup16 (&operands
[0].exp
, M6811_OP_IND16
, M6811_OP_IND16
);
1449 /* Branch with a constant that must fit in 8-bits. */
1450 if (operands
[0].exp
.X_op
== O_constant
)
1452 if (!check_range (n
, opcode
->format
))
1454 as_bad (_("Operand out of range for a relative branch: `%ld'"),
1457 else if (opcode
->format
& M6812_OP_JUMP_REL16
)
1459 f
= m68hc11_new_insn (4);
1460 number_to_chars_bigendian (f
, M6811_OPCODE_PAGE2
, 1);
1461 number_to_chars_bigendian (f
+ 1, code
, 1);
1462 number_to_chars_bigendian (f
+ 2, n
& 0x0ffff, 2);
1466 f
= m68hc11_new_insn (2);
1467 number_to_chars_bigendian (f
, code
, 1);
1468 number_to_chars_bigendian (f
+ 1, n
& 0x0FF, 1);
1471 else if (opcode
->format
& M6812_OP_JUMP_REL16
)
1473 f
= m68hc11_new_insn (2);
1474 number_to_chars_bigendian (f
, M6811_OPCODE_PAGE2
, 1);
1475 number_to_chars_bigendian (f
+ 1, code
, 1);
1476 fixup16 (&operands
[0].exp
, M6812_OP_JUMP_REL16
, M6812_OP_JUMP_REL16
);
1482 /* Branch offset must fit in 8-bits, don't do some relax. */
1483 if (jmp_mode
== 0 && flag_fixed_branchs
)
1485 opcode
= m68hc11_new_insn (1);
1486 number_to_chars_bigendian (opcode
, code
, 1);
1487 fixup8 (&operands
[0].exp
, M6811_OP_JUMP_REL
, M6811_OP_JUMP_REL
);
1490 /* bra/bsr made be changed into jmp/jsr. */
1491 else if (code
== M6811_BSR
|| code
== M6811_BRA
|| code
== M6812_BSR
)
1493 opcode
= m68hc11_new_insn (2);
1494 number_to_chars_bigendian (opcode
, code
, 1);
1495 number_to_chars_bigendian (opcode
+ 1, 0, 1);
1496 frag_var (rs_machine_dependent
, 2, 1,
1497 ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_UNDF
),
1498 operands
[0].exp
.X_add_symbol
, (offsetT
) n
, opcode
);
1500 else if (current_architecture
& cpu6812
)
1502 opcode
= m68hc11_new_insn (2);
1503 number_to_chars_bigendian (opcode
, code
, 1);
1504 number_to_chars_bigendian (opcode
+ 1, 0, 1);
1505 frag_var (rs_machine_dependent
, 2, 2,
1506 ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
, STATE_UNDF
),
1507 operands
[0].exp
.X_add_symbol
, (offsetT
) n
, opcode
);
1511 opcode
= m68hc11_new_insn (2);
1512 number_to_chars_bigendian (opcode
, code
, 1);
1513 number_to_chars_bigendian (opcode
+ 1, 0, 1);
1514 frag_var (rs_machine_dependent
, 3, 3,
1515 ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
, STATE_UNDF
),
1516 operands
[0].exp
.X_add_symbol
, (offsetT
) n
, opcode
);
1521 /* Builds a dbne/dbeq/tbne/tbeq instruction. */
1523 build_dbranch_insn (opcode
, operands
, nb_operands
, jmp_mode
)
1524 struct m68hc11_opcode
*opcode
;
1534 /* The relative branch convertion is not supported for
1536 assert ((opcode
->format
& M6811_OP_BITMASK
) == 0);
1537 assert (nb_operands
== 2);
1538 assert (operands
[0].reg1
!= REG_NONE
);
1540 code
= opcode
->opcode
& 0x0FF;
1543 f
= m68hc11_new_insn (1);
1544 number_to_chars_bigendian (f
, code
, 1);
1546 n
= operands
[1].exp
.X_add_number
;
1547 code
= operands
[0].reg1
;
1549 if (operands
[0].reg1
== REG_NONE
|| operands
[0].reg1
== REG_CCR
1550 || operands
[0].reg1
== REG_PC
)
1551 as_bad (_("Invalid register for dbcc/tbcc instruction."));
1553 if (opcode
->format
& M6812_OP_IBCC_MARKER
)
1555 else if (opcode
->format
& M6812_OP_TBCC_MARKER
)
1558 if (!(opcode
->format
& M6812_OP_EQ_MARKER
))
1561 /* Turn into a long branch:
1562 - when force long branch option (and not for jbcc pseudos),
1563 - when jdbcc and the constant is out of -256..255 range,
1564 - when branch optimization is allowed and branch out of range. */
1565 if ((jmp_mode
== 0 && flag_force_long_jumps
)
1566 || (operands
[1].exp
.X_op
== O_constant
1567 && (!check_range (n
, M6812_OP_IBCC_MARKER
) &&
1568 (jmp_mode
== 1 || flag_fixed_branchs
== 0))))
1572 number_to_chars_bigendian (f
, code
, 1);
1573 number_to_chars_bigendian (f
+ 1, M6812_JMP
, 1);
1574 fixup16 (&operands
[0].exp
, M6811_OP_IND16
, M6811_OP_IND16
);
1578 /* Branch with a constant that must fit in 9-bits. */
1579 if (operands
[1].exp
.X_op
== O_constant
)
1581 if (!check_range (n
, M6812_OP_IBCC_MARKER
))
1583 as_bad (_("Operand out of range for a relative branch: `%ld'"),
1592 number_to_chars_bigendian (f
, code
, 1);
1593 number_to_chars_bigendian (f
+ 1, n
& 0x0FF, 1);
1598 /* Branch offset must fit in 8-bits, don't do some relax. */
1599 if (jmp_mode
== 0 && flag_fixed_branchs
)
1601 fixup8 (&operands
[0].exp
, M6811_OP_JUMP_REL
, M6811_OP_JUMP_REL
);
1607 number_to_chars_bigendian (f
, code
, 1);
1608 number_to_chars_bigendian (f
+ 1, 0, 1);
1609 frag_var (rs_machine_dependent
, 3, 3,
1610 ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_UNDF
),
1611 operands
[1].exp
.X_add_symbol
, (offsetT
) n
, f
);
1616 #define OP_EXTENDED (M6811_OP_PAGE2 | M6811_OP_PAGE3 | M6811_OP_PAGE4)
1618 /* Assemble the post index byte for 68HC12 extended addressing modes. */
1620 build_indexed_byte (op
, format
, move_insn
)
1622 int format ATTRIBUTE_UNUSED
;
1625 unsigned char byte
= 0;
1630 val
= op
->exp
.X_add_number
;
1632 if (mode
& M6812_AUTO_INC_DEC
)
1635 if (mode
& (M6812_POST_INC
| M6812_POST_DEC
))
1638 if (op
->exp
.X_op
== O_constant
)
1640 if (!check_range (val
, mode
))
1642 as_bad (_("Increment/decrement value is out of range: `%ld'."),
1645 if (mode
& (M6812_POST_INC
| M6812_PRE_INC
))
1646 byte
|= (val
- 1) & 0x07;
1648 byte
|= (8 - ((val
) & 7)) | 0x8;
1653 as_fatal (_("Expecting a register."));
1668 as_bad (_("Invalid register for post/pre increment."));
1673 number_to_chars_bigendian (f
, byte
, 1);
1677 if (mode
& M6812_OP_IDX
)
1698 as_bad (_("Invalid register."));
1701 if (op
->exp
.X_op
== O_constant
)
1703 if (!check_range (val
, M6812_OP_IDX
))
1705 as_bad (_("Offset out of 16-bit range: %ld."), val
);
1708 if (move_insn
&& !(val
>= -16 && val
<= 15))
1710 as_bad (_("Offset out of 5-bit range for movw/movb insn: %ld."),
1715 if (val
>= -16 && val
<= 15 && !(mode
& M6812_OP_IDX_2
))
1720 number_to_chars_bigendian (f
, byte
, 1);
1723 else if (val
>= -256 && val
<= 255 && !(mode
& M6812_OP_IDX_2
))
1730 number_to_chars_bigendian (f
, byte
, 1);
1731 number_to_chars_bigendian (f
+ 1, val
& 0x0FF, 1);
1737 if (mode
& M6812_OP_IDX_2
)
1743 number_to_chars_bigendian (f
, byte
, 1);
1744 number_to_chars_bigendian (f
+ 1, val
& 0x0FFFF, 2);
1748 if (op
->reg1
!= REG_PC
)
1750 byte
= (byte
<< 3) | 0xe2;
1752 number_to_chars_bigendian (f
, byte
, 1);
1755 fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 2,
1756 &op
->exp
, false, BFD_RELOC_16
);
1757 number_to_chars_bigendian (f
, 0, 2);
1762 number_to_chars_bigendian (f
, byte
, 1);
1763 frag_var (rs_machine_dependent
, 2, 2,
1764 ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_UNDF
),
1765 op
->exp
.X_add_symbol
,
1766 op
->exp
.X_add_number
, f
);
1771 if (mode
& M6812_OP_REG
)
1773 if (mode
& M6812_OP_IDX_2
)
1775 if (op
->reg1
!= REG_D
)
1776 as_bad (_("Expecting register D for indexed indirect mode."));
1778 as_bad (_("Indexed indirect mode is not allowed for movb/movw."));
1795 as_bad (_("Invalid accumulator register."));
1820 as_bad (_("Invalid indexed register."));
1824 number_to_chars_bigendian (f
, byte
, 1);
1828 as_fatal (_("Addressing mode not implemented yet."));
1832 /* Assemble the 68HC12 register mode byte. */
1834 build_reg_mode (op
, format
)
1841 if (format
& M6812_OP_SEX_MARKER
1842 && op
->reg1
!= REG_A
&& op
->reg1
!= REG_B
&& op
->reg1
!= REG_CCR
)
1843 as_bad (_("Invalid source register for this instruction, use 'tfr'."));
1844 else if (op
->reg1
== REG_NONE
|| op
->reg1
== REG_PC
)
1845 as_bad (_("Invalid source register."));
1847 if (format
& M6812_OP_SEX_MARKER
1848 && op
->reg2
!= REG_D
1849 && op
->reg2
!= REG_X
&& op
->reg2
!= REG_Y
&& op
->reg2
!= REG_SP
)
1850 as_bad (_("Invalid destination register for this instruction, use 'tfr'."));
1851 else if (op
->reg2
== REG_NONE
|| op
->reg2
== REG_PC
)
1852 as_bad (_("Invalid destination register."));
1854 byte
= (op
->reg1
<< 4) | (op
->reg2
);
1855 if (format
& M6812_OP_EXG_MARKER
)
1859 number_to_chars_bigendian (f
, byte
, 1);
1863 /* build_insn takes a pointer to the opcode entry in the opcode table,
1864 the array of operand expressions and builds the correspding instruction.
1865 This operation only deals with non relative jumps insn (need special
1868 build_insn (opcode
, operands
, nb_operands
)
1869 struct m68hc11_opcode
*opcode
;
1871 int nb_operands ATTRIBUTE_UNUSED
;
1879 /* Put the page code instruction if there is one. */
1880 format
= opcode
->format
;
1881 if (format
& OP_EXTENDED
)
1885 f
= m68hc11_new_insn (2);
1886 if (format
& M6811_OP_PAGE2
)
1887 page_code
= M6811_OPCODE_PAGE2
;
1888 else if (format
& M6811_OP_PAGE3
)
1889 page_code
= M6811_OPCODE_PAGE3
;
1891 page_code
= M6811_OPCODE_PAGE4
;
1893 number_to_chars_bigendian (f
, page_code
, 1);
1898 f
= m68hc11_new_insn (1);
1900 number_to_chars_bigendian (f
, opcode
->opcode
, 1);
1904 /* The 68HC12 movb and movw instructions are special. We have to handle
1905 them in a special way. */
1906 if (format
& (M6812_OP_IND16_P2
| M6812_OP_IDX_P2
))
1909 if (format
& M6812_OP_IDX
)
1911 insn_size
+= build_indexed_byte (&operands
[0], format
, 1);
1913 format
&= ~M6812_OP_IDX
;
1915 if (format
& M6812_OP_IDX_P2
)
1917 insn_size
+= build_indexed_byte (&operands
[1], format
, 1);
1919 format
&= ~M6812_OP_IDX_P2
;
1923 if (format
& (M6811_OP_DIRECT
| M6811_OP_IMM8
))
1926 fixup8 (&operands
[i
].exp
,
1927 format
& (M6811_OP_DIRECT
| M6811_OP_IMM8
| M6812_OP_TRAP_ID
),
1931 else if (format
& (M6811_OP_IMM16
| M6811_OP_IND16
))
1934 fixup16 (&operands
[i
].exp
, format
& (M6811_OP_IMM16
| M6811_OP_IND16
),
1938 else if (format
& (M6811_OP_IX
| M6811_OP_IY
))
1940 if ((format
& M6811_OP_IX
) && (operands
[0].reg1
!= REG_X
))
1941 as_bad (_("Invalid indexed register, expecting register X."));
1942 if ((format
& M6811_OP_IY
) && (operands
[0].reg1
!= REG_Y
))
1943 as_bad (_("Invalid indexed register, expecting register Y."));
1946 fixup8 (&operands
[0].exp
, M6811_OP_IX
, operands
[0].mode
);
1950 (M6812_OP_IDX
| M6812_OP_IDX_2
| M6812_OP_IDX_1
| M6812_OP_D_IDX
))
1952 insn_size
+= build_indexed_byte (&operands
[i
], format
, move_insn
);
1955 else if (format
& M6812_OP_REG
&& current_architecture
& cpu6812
)
1957 insn_size
+= build_reg_mode (&operands
[i
], format
);
1960 if (format
& M6811_OP_BITMASK
)
1963 fixup8 (&operands
[i
].exp
, M6811_OP_BITMASK
, operands
[i
].mode
);
1966 if (format
& M6811_OP_JUMP_REL
)
1969 fixup8 (&operands
[i
].exp
, M6811_OP_JUMP_REL
, operands
[i
].mode
);
1972 else if (format
& M6812_OP_IND16_P2
)
1975 fixup16 (&operands
[1].exp
, M6811_OP_IND16
, operands
[1].mode
);
1979 /* Opcode identification and operand analysis. */
1981 /* find() gets a pointer to an entry in the opcode table. It must look at all
1982 opcodes with the same name and use the operands to choose the correct
1983 opcode. Returns the opcode pointer if there was a match and 0 if none. */
1984 static struct m68hc11_opcode
*
1985 find (opc
, operands
, nb_operands
)
1986 struct m68hc11_opcode_def
*opc
;
1991 struct m68hc11_opcode
*opcode
;
1992 struct m68hc11_opcode
*op_indirect
;
1995 opcode
= opc
->opcode
;
1997 /* Now search the opcode table table for one with operands
1998 that matches what we've got. We're only done if the operands matched so
1999 far AND there are no more to check. */
2000 for (pos
= match
= 0; match
== 0 && pos
< opc
->nb_modes
; pos
++, opcode
++)
2002 int poss_indirect
= 0;
2003 long format
= opcode
->format
;
2007 if (opcode
->format
& M6811_OP_MASK
)
2009 if (opcode
->format
& M6811_OP_BITMASK
)
2011 if (opcode
->format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
2013 if (opcode
->format
& (M6812_OP_IND16_P2
| M6812_OP_IDX_P2
))
2016 for (i
= 0; expect
== nb_operands
&& i
< nb_operands
; i
++)
2018 int mode
= operands
[i
].mode
;
2020 if (mode
& M6811_OP_IMM16
)
2023 (M6811_OP_IMM8
| M6811_OP_IMM16
| M6811_OP_BITMASK
))
2027 if (mode
== M6811_OP_DIRECT
)
2029 if (format
& M6811_OP_DIRECT
)
2032 /* If the operand is a page 0 operand, remember a
2033 possible <abs-16> addressing mode. We mark
2034 this and continue to check other operands. */
2035 if (format
& M6811_OP_IND16
2036 && flag_strict_direct_addressing
&& op_indirect
== 0)
2043 if (mode
& M6811_OP_IND16
)
2045 if (i
== 0 && (format
& M6811_OP_IND16
) != 0)
2047 if (i
!= 0 && (format
& M6812_OP_IND16_P2
) != 0)
2049 if (i
== 0 && (format
& M6811_OP_BITMASK
))
2052 if (mode
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
2054 if (format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
2057 if (mode
& M6812_OP_REG
)
2060 && (format
& M6812_OP_REG
)
2061 && (operands
[i
].reg2
== REG_NONE
))
2064 && (format
& M6812_OP_REG
)
2065 && (format
& M6812_OP_REG_2
)
2066 && (operands
[i
].reg2
!= REG_NONE
))
2069 && (format
& M6812_OP_IDX
)
2070 && (operands
[i
].reg2
!= REG_NONE
))
2073 && (format
& M6812_OP_D_IDX
))
2076 && (format
& M6812_OP_IDX
)
2077 && (format
& (M6812_OP_IND16_P2
| M6812_OP_IDX_P2
)))
2080 && (format
& M6812_OP_IDX_P2
))
2084 if (mode
& M6812_OP_IDX
)
2086 if (format
& M6811_OP_IX
&& operands
[i
].reg1
== REG_X
)
2088 if (format
& M6811_OP_IY
&& operands
[i
].reg1
== REG_Y
)
2091 && format
& (M6812_OP_IDX
| M6812_OP_IDX_1
| M6812_OP_IDX_2
)
2092 && (operands
[i
].reg1
== REG_X
2093 || operands
[i
].reg1
== REG_Y
2094 || operands
[i
].reg1
== REG_SP
2095 || operands
[i
].reg1
== REG_PC
))
2097 if (i
== 1 && format
& M6812_OP_IDX_P2
)
2100 if (mode
& M6812_AUTO_INC_DEC
)
2103 && format
& (M6812_OP_IDX
| M6812_OP_IDX_1
|
2106 if (i
== 1 && format
& M6812_OP_IDX_P2
)
2111 match
= i
== nb_operands
;
2113 /* Operands are ok but an operand uses page 0 addressing mode
2114 while the insn supports abs-16 mode. Keep a reference to this
2115 insns in case there is no insn supporting page 0 addressing. */
2116 if (match
&& poss_indirect
)
2118 op_indirect
= opcode
;
2125 /* Page 0 addressing is used but not supported by any insn.
2126 If absolute addresses are supported, we use that insn. */
2127 if (match
== 0 && op_indirect
)
2129 opcode
= op_indirect
;
2141 /* Find the real opcode and its associated operands. We use a progressive
2142 approach here. On entry, 'opc' points to the first opcode in the
2143 table that matches the opcode name in the source line. We try to
2144 isolate an operand, find a possible match in the opcode table.
2145 We isolate another operand if no match were found. The table 'operands'
2146 is filled while operands are recognized.
2148 Returns the opcode pointer that matches the opcode name in the
2149 source line and the associated operands. */
2150 static struct m68hc11_opcode
*
2151 find_opcode (opc
, operands
, nb_operands
)
2152 struct m68hc11_opcode_def
*opc
;
2156 struct m68hc11_opcode
*opcode
;
2159 if (opc
->max_operands
== 0)
2165 for (i
= 0; i
< opc
->max_operands
;)
2169 result
= get_operand (&operands
[i
], i
, opc
->format
);
2173 /* Special case where the bitmask of the bclr/brclr
2174 instructions is not introduced by #.
2175 Example: bclr 3,x $80. */
2176 if (i
== 1 && (opc
->format
& M6811_OP_BITMASK
)
2177 && (operands
[i
].mode
& M6811_OP_IND16
))
2179 operands
[i
].mode
= M6811_OP_IMM16
;
2184 if (i
>= opc
->min_operands
)
2186 opcode
= find (opc
, operands
, i
);
2191 if (*input_line_pointer
== ',')
2192 input_line_pointer
++;
2198 #define M6812_XBCC_MARKER (M6812_OP_TBCC_MARKER \
2199 | M6812_OP_DBCC_MARKER \
2200 | M6812_OP_IBCC_MARKER)
2202 /* Gas line assembler entry point. */
2204 /* This is the main entry point for the machine-dependent assembler. str
2205 points to a machine-dependent instruction. This function is supposed to
2206 emit the frags/bytes it assembles to. */
2211 struct m68hc11_opcode_def
*opc
;
2212 struct m68hc11_opcode
*opcode
;
2214 unsigned char *op_start
, *save
;
2215 unsigned char *op_end
;
2218 operand operands
[M6811_MAX_OPERANDS
];
2220 int branch_optimize
= 0;
2223 /* Drop leading whitespace. */
2227 /* Find the opcode end and get the opcode in 'name'. The opcode is forced
2228 lower case (the opcode table only has lower case op-codes). */
2229 for (op_start
= op_end
= (unsigned char *) (str
);
2230 *op_end
&& nlen
< 20 && !is_end_of_line
[*op_end
] && *op_end
!= ' ';
2233 name
[nlen
] = tolower (op_start
[nlen
]);
2240 as_bad (_("No instruction or missing opcode."));
2244 /* Find the opcode definition given its name. */
2245 opc
= (struct m68hc11_opcode_def
*) hash_find (m68hc11_hash
, name
);
2247 /* If it's not recognized, look for 'jbsr' and 'jbxx'. These are
2248 pseudo insns for relative branch. For these branchs, we always
2249 optimize them (turned into absolute branchs) even if --short-branchs
2251 if (opc
== NULL
&& name
[0] == 'j' && name
[1] == 'b')
2253 opc
= (struct m68hc11_opcode_def
*) hash_find (m68hc11_hash
, &name
[1]);
2255 && (!(opc
->format
& M6811_OP_JUMP_REL
)
2256 || (opc
->format
& M6811_OP_BITMASK
)))
2259 branch_optimize
= 1;
2262 /* The following test should probably be removed. This is not conform
2263 to Motorola assembler specs. */
2264 if (opc
== NULL
&& flag_mri
)
2266 if (*op_end
== ' ' || *op_end
== '\t')
2268 while (*op_end
== ' ' || *op_end
== '\t')
2273 (is_end_of_line
[op_end
[1]]
2274 || op_end
[1] == ' ' || op_end
[1] == '\t'
2275 || !isalnum (op_end
[1])))
2276 && (*op_end
== 'a' || *op_end
== 'b'
2277 || *op_end
== 'A' || *op_end
== 'B'
2278 || *op_end
== 'd' || *op_end
== 'D'
2279 || *op_end
== 'x' || *op_end
== 'X'
2280 || *op_end
== 'y' || *op_end
== 'Y'))
2282 name
[nlen
++] = tolower (*op_end
++);
2284 opc
= (struct m68hc11_opcode_def
*) hash_find (m68hc11_hash
,
2290 /* Identify a possible instruction alias. There are some on the
2291 68HC12 to emulate a fiew 68HC11 instructions. */
2292 if (opc
== NULL
&& (current_architecture
& cpu6812
))
2296 for (i
= 0; i
< m68hc12_num_alias
; i
++)
2297 if (strcmp (m68hc12_alias
[i
].name
, name
) == 0)
2303 if (opc
== NULL
&& alias_id
< 0)
2305 as_bad (_("Opcode `%s' is not recognized."), name
);
2308 save
= input_line_pointer
;
2309 input_line_pointer
= op_end
;
2314 opcode
= find_opcode (opc
, operands
, &nb_operands
);
2319 if ((opcode
|| alias_id
>= 0) && !flag_mri
)
2321 char *p
= input_line_pointer
;
2323 while (*p
== ' ' || *p
== '\t' || *p
== '\n' || *p
== '\r')
2326 if (*p
!= '\n' && *p
)
2327 as_bad (_("Garbage at end of instruction: `%s'."), p
);
2330 input_line_pointer
= save
;
2334 char *f
= m68hc11_new_insn (m68hc12_alias
[alias_id
].size
);
2336 number_to_chars_bigendian (f
, m68hc12_alias
[alias_id
].code1
, 1);
2337 if (m68hc12_alias
[alias_id
].size
> 1)
2338 number_to_chars_bigendian (f
+ 1, m68hc12_alias
[alias_id
].code2
, 1);
2343 /* Opcode is known but does not have valid operands. Print out the
2344 syntax for this opcode. */
2347 if (flag_print_insn_syntax
)
2348 print_insn_format (name
);
2350 as_bad (_("Invalid operand for `%s'"), name
);
2354 /* Treat dbeq/ibeq/tbeq instructions in a special way. The branch is
2355 relative and must be in the range -256..255 (9-bits). */
2356 if ((opcode
->format
& M6812_XBCC_MARKER
)
2357 && (opcode
->format
& M6811_OP_JUMP_REL
))
2358 build_dbranch_insn (opcode
, operands
, nb_operands
);
2360 /* Relative jumps instructions are taken care of separately. We have to make
2361 sure that the relative branch is within the range -128..127. If it's out
2362 of range, the instructions are changed into absolute instructions.
2363 This is not supported for the brset and brclr instructions. */
2364 else if ((opcode
->format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
2365 && !(opcode
->format
& M6811_OP_BITMASK
))
2366 build_jump_insn (opcode
, operands
, nb_operands
, branch_optimize
);
2368 build_insn (opcode
, operands
, nb_operands
);
2371 /* Relocation, relaxation and frag conversions. */
2373 md_pcrel_from_section (fixp
, sec
)
2378 if (fixp
->fx_addsy
!= (symbolS
*) NULL
2379 && (!S_IS_DEFINED (fixp
->fx_addsy
)
2380 || (S_GET_SEGMENT (fixp
->fx_addsy
) != sec
)))
2383 adjust
= fixp
->fx_pcrel_adjust
;
2384 return fixp
->fx_frag
->fr_address
+ fixp
->fx_where
+ adjust
;
2387 /* If while processing a fixup, a reloc really needs to be created
2388 then it is done here. */
2390 tc_gen_reloc (section
, fixp
)
2396 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
2397 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
2398 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
2399 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
2400 if (fixp
->fx_r_type
== 0)
2401 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_16
);
2403 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
2404 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
2406 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2407 _("Relocation %d is not supported by object file format."),
2408 (int) fixp
->fx_r_type
);
2412 if (!fixp
->fx_pcrel
)
2413 reloc
->addend
= fixp
->fx_addnumber
;
2415 reloc
->addend
= (section
->vma
2416 + (fixp
->fx_pcrel_adjust
== 64
2417 ? -1 : fixp
->fx_pcrel_adjust
)
2418 + fixp
->fx_addnumber
2419 + md_pcrel_from_section (fixp
, section
));
2424 md_convert_frag (abfd
, sec
, fragP
)
2425 bfd
*abfd ATTRIBUTE_UNUSED
;
2426 asection
*sec ATTRIBUTE_UNUSED
;
2432 char *buffer_address
= fragP
->fr_literal
;
2434 /* Address in object code of the displacement. */
2435 register int object_address
= fragP
->fr_fix
+ fragP
->fr_address
;
2437 buffer_address
+= fragP
->fr_fix
;
2439 /* The displacement of the address, from current location. */
2440 value
= fragP
->fr_symbol
? S_GET_VALUE (fragP
->fr_symbol
) : 0;
2441 disp
= (value
+ fragP
->fr_offset
) - object_address
;
2442 disp
+= symbol_get_frag (fragP
->fr_symbol
)->fr_address
;
2444 switch (fragP
->fr_subtype
)
2446 case ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_BYTE
):
2447 fragP
->fr_opcode
[1] = disp
;
2450 case ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_WORD
):
2451 /* This relax is only for bsr and bra. */
2452 assert (IS_OPCODE (fragP
->fr_opcode
[0], M6811_BSR
)
2453 || IS_OPCODE (fragP
->fr_opcode
[0], M6811_BRA
)
2454 || IS_OPCODE (fragP
->fr_opcode
[0], M6812_BSR
));
2456 fragP
->fr_opcode
[0] = convert_branch (fragP
->fr_opcode
[0]);
2458 fix_new (fragP
, fragP
->fr_fix
- 1, 2,
2459 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_16
);
2463 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
, STATE_BYTE
):
2464 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
, STATE_BYTE
):
2465 fragP
->fr_opcode
[1] = disp
;
2468 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
, STATE_WORD
):
2469 /* Invert branch. */
2470 fragP
->fr_opcode
[0] ^= 1;
2471 fragP
->fr_opcode
[1] = 3; /* Branch offset. */
2472 buffer_address
[0] = M6811_JMP
;
2473 fix_new (fragP
, fragP
->fr_fix
+ 1, 2,
2474 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_16
);
2478 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
, STATE_WORD
):
2479 /* Translate branch into a long branch. */
2480 fragP
->fr_opcode
[1] = fragP
->fr_opcode
[0];
2481 fragP
->fr_opcode
[0] = M6811_OPCODE_PAGE2
;
2483 fixp
= fix_new (fragP
, fragP
->fr_fix
, 2,
2484 fragP
->fr_symbol
, fragP
->fr_offset
, 1,
2485 BFD_RELOC_16_PCREL
);
2486 fixp
->fx_pcrel_adjust
= 2;
2490 case ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS5
):
2491 fragP
->fr_opcode
[0] = fragP
->fr_opcode
[0] << 6;
2492 if ((fragP
->fr_opcode
[0] & 0x0ff) == 0x0c0)
2493 fragP
->fr_opcode
[0] |= disp
& 0x1f;
2495 fragP
->fr_opcode
[0] |= value
& 0x1f;
2498 case ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS9
):
2499 fragP
->fr_opcode
[0] = (fragP
->fr_opcode
[0] << 3);
2500 fragP
->fr_opcode
[0] |= 0xE0;
2501 fix_new (fragP
, fragP
->fr_fix
, 1,
2502 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_8
);
2506 case ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS16
):
2507 fragP
->fr_opcode
[0] = (fragP
->fr_opcode
[0] << 3);
2508 fragP
->fr_opcode
[0] |= 0xe2;
2509 if ((fragP
->fr_opcode
[0] & 0x0ff) == 0x0fa)
2511 fixp
= fix_new (fragP
, fragP
->fr_fix
, 2,
2512 fragP
->fr_symbol
, fragP
->fr_offset
,
2513 1, BFD_RELOC_16_PCREL
);
2514 fixp
->fx_pcrel_adjust
= 2;
2518 fix_new (fragP
, fragP
->fr_fix
, 2,
2519 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_16
);
2524 case ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_BYTE
):
2526 fragP
->fr_opcode
[0] |= 0x10;
2528 fragP
->fr_opcode
[1] = disp
& 0x0FF;
2531 case ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_WORD
):
2532 /* Invert branch. */
2533 fragP
->fr_opcode
[0] ^= 0x20;
2534 fragP
->fr_opcode
[1] = 3; /* Branch offset. */
2535 buffer_address
[0] = M6812_JMP
;
2536 fix_new (fragP
, fragP
->fr_fix
+ 1, 2,
2537 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_16
);
2546 /* On an ELF system, we can't relax an externally visible symbol,
2547 as well as a weak symbol. The weak symbol can be overriden
2548 at final link time by a non weak symbol. */
2550 relaxable_symbol (symbol
)
2553 return ! S_IS_EXTERNAL (symbol
) && ! S_IS_WEAK (symbol
);
2556 /* Force truly undefined symbols to their maximum size, and generally set up
2557 the frag list to be relaxed. */
2559 md_estimate_size_before_relax (fragP
, segment
)
2564 char *buffer_address
= fragP
->fr_fix
+ fragP
->fr_literal
;
2566 old_fr_fix
= fragP
->fr_fix
;
2568 switch (fragP
->fr_subtype
)
2570 case ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_UNDF
):
2572 /* This relax is only for bsr and bra. */
2573 assert (IS_OPCODE (fragP
->fr_opcode
[0], M6811_BSR
)
2574 || IS_OPCODE (fragP
->fr_opcode
[0], M6811_BRA
)
2575 || IS_OPCODE (fragP
->fr_opcode
[0], M6812_BSR
));
2577 /* A relaxable case. */
2578 if (S_GET_SEGMENT (fragP
->fr_symbol
) == segment
2579 && relaxable_symbol (fragP
->fr_symbol
))
2581 fragP
->fr_subtype
= ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_BYTE
);
2585 if (flag_fixed_branchs
)
2586 as_bad_where (fragP
->fr_file
, fragP
->fr_line
,
2587 _("bra or bsr with undefined symbol."));
2589 /* The symbol is undefined or in a separate section. Turn bra into a
2590 jmp and bsr into a jsr. The insn becomes 3 bytes long (instead of
2591 2). A fixup is necessary for the unresolved symbol address. */
2593 fragP
->fr_opcode
[0] = convert_branch (fragP
->fr_opcode
[0]);
2596 fix_new (fragP
, old_fr_fix
- 1, 2, fragP
->fr_symbol
,
2597 fragP
->fr_offset
, 0, BFD_RELOC_16
);
2602 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
, STATE_UNDF
):
2603 assert (current_architecture
& cpu6811
);
2605 if (S_GET_SEGMENT (fragP
->fr_symbol
) == segment
2606 && relaxable_symbol (fragP
->fr_symbol
))
2608 fragP
->fr_subtype
= ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
,
2613 fragP
->fr_opcode
[0] ^= 1; /* Reverse sense of branch. */
2614 fragP
->fr_opcode
[1] = 3; /* Skip next jmp insn (3 bytes). */
2616 /* Don't use fr_opcode[2] because this may be
2617 in a different frag. */
2618 buffer_address
[0] = M6811_JMP
;
2621 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
2622 fragP
->fr_offset
, 0, BFD_RELOC_16
);
2628 case ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_UNDF
):
2629 assert (current_architecture
& cpu6812
);
2631 if (S_GET_SEGMENT (fragP
->fr_symbol
) == segment
2632 && relaxable_symbol (fragP
->fr_symbol
))
2634 fragP
->fr_subtype
= ENCODE_RELAX (STATE_INDEXED_OFFSET
,
2639 /* Switch the indexed operation to 16-bit mode. */
2640 fragP
->fr_opcode
[0] = fragP
->fr_opcode
[0] << 3;
2641 fragP
->fr_opcode
[0] |= 0xe2;
2643 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
2644 fragP
->fr_offset
, 0, BFD_RELOC_16
);
2650 case ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_UNDF
):
2651 assert (current_architecture
& cpu6812
);
2653 if (S_GET_SEGMENT (fragP
->fr_symbol
) == segment
2654 && relaxable_symbol (fragP
->fr_symbol
))
2656 fragP
->fr_subtype
= ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_BYTE
);
2660 fragP
->fr_opcode
[0] ^= 0x20; /* Reverse sense of branch. */
2661 fragP
->fr_opcode
[1] = 3; /* Skip next jmp insn (3 bytes). */
2663 /* Don't use fr_opcode[2] because this may be
2664 in a different frag. */
2665 buffer_address
[0] = M6812_JMP
;
2668 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
2669 fragP
->fr_offset
, 0, BFD_RELOC_16
);
2675 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
, STATE_UNDF
):
2676 assert (current_architecture
& cpu6812
);
2678 if (S_GET_SEGMENT (fragP
->fr_symbol
) == segment
2679 && relaxable_symbol (fragP
->fr_symbol
))
2681 fragP
->fr_subtype
= ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
,
2686 /* Translate into a lbcc branch. */
2687 fragP
->fr_opcode
[1] = fragP
->fr_opcode
[0];
2688 fragP
->fr_opcode
[0] = M6811_OPCODE_PAGE2
;
2690 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
2691 fragP
->fr_offset
, 0, BFD_RELOC_16_PCREL
);
2698 as_fatal (_("Subtype %d is not recognized."), fragP
->fr_subtype
);
2701 return (fragP
->fr_fix
- old_fr_fix
);
2705 md_apply_fix (fixp
, valuep
)
2713 if (fixp
->fx_addsy
== (symbolS
*) NULL
)
2718 else if (fixp
->fx_pcrel
)
2724 value
= fixp
->fx_offset
;
2725 if (fixp
->fx_subsy
!= (symbolS
*) NULL
)
2727 if (S_GET_SEGMENT (fixp
->fx_subsy
) == absolute_section
)
2729 value
-= S_GET_VALUE (fixp
->fx_subsy
);
2733 /* We don't actually support subtracting a symbol. */
2734 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2735 _("Expression too complex."));
2740 op_type
= fixp
->fx_r_type
;
2742 /* Patch the instruction with the resolved operand. Elf relocation
2743 info will also be generated to take care of linker/loader fixups.
2744 The 68HC11 addresses only 64Kb, we are only concerned by 8 and 16-bit
2745 relocs. BFD_RELOC_8 is basically used for .page0 access (the linker
2746 will warn for overflows). BFD_RELOC_8_PCREL should not be generated
2747 because it's either resolved or turned out into non-relative insns (see
2748 relax table, bcc, bra, bsr transformations)
2750 The BFD_RELOC_32 is necessary for the support of --gstabs. */
2751 where
= fixp
->fx_frag
->fr_literal
+ fixp
->fx_where
;
2753 switch (fixp
->fx_r_type
)
2756 bfd_putb32 ((bfd_vma
) value
, (unsigned char *) where
);
2760 case BFD_RELOC_16_PCREL
:
2761 bfd_putb16 ((bfd_vma
) value
, (unsigned char *) where
);
2762 if (value
< -65537 || value
> 65535)
2763 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2764 _("Value out of 16-bit range."));
2767 case BFD_RELOC_M68HC11_HI8
:
2771 case BFD_RELOC_M68HC11_LO8
:
2774 bfd_putb8 ((bfd_vma
) value
, (unsigned char *) where
);
2776 ((bfd_byte
*) where
)[0] = (bfd_byte
) value
;
2779 case BFD_RELOC_8_PCREL
:
2781 bfd_putb8 ((bfd_vma
) value
, (unsigned char *) where
);
2783 ((bfd_byte
*) where
)[0] = (bfd_byte
) value
;
2785 if (value
< -128 || value
> 127)
2786 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2787 _("Value %ld too large for 8-bit PC-relative branch."),
2791 case BFD_RELOC_M68HC11_3B
:
2792 if (value
<= 0 || value
> 8)
2793 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2794 _("Auto increment/decrement offset '%ld' is out of range."),
2801 where
[0] = where
[0] | (value
& 0x07);
2805 as_fatal (_("Line %d: unknown relocation type: 0x%x."),
2806 fixp
->fx_line
, fixp
->fx_r_type
);