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},
230 /* Dwarf2 support for Gcc. */
231 {"file", dwarf2_directive_file
, 0},
232 {"loc", dwarf2_directive_loc
, 0},
237 /* Options and initialization. */
239 CONST
char *md_shortopts
= "Sm:";
241 struct option md_longopts
[] = {
242 #define OPTION_FORCE_LONG_BRANCH (OPTION_MD_BASE)
243 {"force-long-branchs", no_argument
, NULL
, OPTION_FORCE_LONG_BRANCH
},
245 #define OPTION_SHORT_BRANCHS (OPTION_MD_BASE + 1)
246 {"short-branchs", no_argument
, NULL
, OPTION_SHORT_BRANCHS
},
248 #define OPTION_STRICT_DIRECT_MODE (OPTION_MD_BASE + 2)
249 {"strict-direct-mode", no_argument
, NULL
, OPTION_STRICT_DIRECT_MODE
},
251 #define OPTION_PRINT_INSN_SYNTAX (OPTION_MD_BASE + 3)
252 {"print-insn-syntax", no_argument
, NULL
, OPTION_PRINT_INSN_SYNTAX
},
254 #define OPTION_PRINT_OPCODES (OPTION_MD_BASE + 4)
255 {"print-opcodes", no_argument
, NULL
, OPTION_PRINT_OPCODES
},
257 #define OPTION_GENERATE_EXAMPLE (OPTION_MD_BASE + 5)
258 {"generate-example", no_argument
, NULL
, OPTION_GENERATE_EXAMPLE
},
260 {NULL
, no_argument
, NULL
, 0}
262 size_t md_longopts_size
= sizeof (md_longopts
);
264 /* Get the target cpu for the assembler. This is based on the configure
265 options and on the -m68hc11/-m68hc12 option. If no option is specified,
266 we must get the default. */
268 m68hc11_arch_format ()
270 get_default_target ();
271 if (current_architecture
& cpu6811
)
272 return "elf32-m68hc11";
274 return "elf32-m68hc12";
277 enum bfd_architecture
280 get_default_target ();
281 if (current_architecture
& cpu6811
)
282 return bfd_arch_m68hc11
;
284 return bfd_arch_m68hc12
;
293 /* Listing header selected according to cpu. */
295 m68hc11_listing_header ()
297 if (current_architecture
& cpu6811
)
298 return "M68HC11 GAS ";
300 return "M68HC12 GAS ";
304 md_show_usage (stream
)
307 get_default_target ();
308 fprintf (stream
, _("\
309 Motorola 68HC11/68HC12 options:\n\
310 -m68hc11 | -m68hc12 specify the processor [default %s]\n\
311 --force-long-branchs always turn relative branchs into absolute ones\n\
312 -S,--short-branchs do not turn relative branchs into absolute ones\n\
313 when the offset is out of range\n\
314 --strict-direct-mode do not turn the direct mode into extended mode\n\
315 when the instruction does not support direct mode\n\
316 --print-insn-syntax print the syntax of instruction in case of error\n\
317 --print-opcodes print the list of instructions with syntax\n\
318 --generate-example generate an example of each instruction\n\
319 (used for testing)\n"), default_cpu
);
323 /* Try to identify the default target based on the BFD library. */
325 get_default_target ()
327 const bfd_target
*target
;
330 if (current_architecture
!= 0)
333 default_cpu
= "unknown";
334 target
= bfd_find_target (0, &abfd
);
335 if (target
&& target
->name
)
337 if (strcmp (target
->name
, "elf32-m68hc12") == 0)
339 current_architecture
= cpu6812
;
340 default_cpu
= "m68hc12";
342 else if (strcmp (target
->name
, "elf32-m68hc11") == 0)
344 current_architecture
= cpu6811
;
345 default_cpu
= "m68hc11";
349 as_bad (_("Default target `%s' is not supported."), target
->name
);
355 m68hc11_print_statistics (file
)
359 struct m68hc11_opcode_def
*opc
;
361 hash_print_statistics (file
, "opcode table", m68hc11_hash
);
363 opc
= m68hc11_opcode_defs
;
364 if (opc
== 0 || m68hc11_nb_opcode_defs
== 0)
367 /* Dump the opcode statistics table. */
368 fprintf (file
, _("Name # Modes Min ops Max ops Modes mask # Used\n"));
369 for (i
= 0; i
< m68hc11_nb_opcode_defs
; i
++, opc
++)
371 fprintf (file
, "%-7.7s %5d %7d %7d 0x%08lx %7d\n",
374 opc
->min_operands
, opc
->max_operands
, opc
->format
, opc
->used
);
379 md_parse_option (c
, arg
)
383 get_default_target ();
386 /* -S means keep external to 2 bit offset rather than 16 bit one. */
387 case OPTION_SHORT_BRANCHS
:
389 flag_fixed_branchs
= 1;
392 case OPTION_FORCE_LONG_BRANCH
:
393 flag_force_long_jumps
= 1;
396 case OPTION_PRINT_INSN_SYNTAX
:
397 flag_print_insn_syntax
= 1;
400 case OPTION_PRINT_OPCODES
:
401 flag_print_opcodes
= 1;
404 case OPTION_STRICT_DIRECT_MODE
:
405 flag_strict_direct_addressing
= 0;
408 case OPTION_GENERATE_EXAMPLE
:
409 flag_print_opcodes
= 2;
413 if (strcasecmp (arg
, "68hc11") == 0)
414 current_architecture
= cpu6811
;
415 else if (strcasecmp (arg
, "68hc12") == 0)
416 current_architecture
= cpu6812
;
418 as_bad (_("Option `%s' is not recognized."), arg
);
429 md_undefined_symbol (name
)
430 char *name ATTRIBUTE_UNUSED
;
435 /* Equal to MAX_PRECISION in atof-ieee.c. */
436 #define MAX_LITTLENUMS 6
438 /* Turn a string in input_line_pointer into a floating point constant
439 of type TYPE, and store the appropriate bytes in *LITP. The number
440 of LITTLENUMS emitted is stored in *SIZEP. An error message is
441 returned, or NULL on OK. */
443 md_atof (type
, litP
, sizeP
)
449 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
450 LITTLENUM_TYPE
*wordP
;
481 return _("Bad call to MD_ATOF()");
483 t
= atof_ieee (input_line_pointer
, type
, words
);
485 input_line_pointer
= t
;
487 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
488 for (wordP
= words
; prec
--;)
490 md_number_to_chars (litP
, (long) (*wordP
++), sizeof (LITTLENUM_TYPE
));
491 litP
+= sizeof (LITTLENUM_TYPE
);
497 md_section_align (seg
, addr
)
501 int align
= bfd_get_section_alignment (stdoutput
, seg
);
502 return ((addr
+ (1 << align
) - 1) & (-1 << align
));
506 cmp_opcode (op1
, op2
)
507 struct m68hc11_opcode
*op1
;
508 struct m68hc11_opcode
*op2
;
510 return strcmp (op1
->name
, op2
->name
);
513 /* Initialize the assembler. Create the opcode hash table
514 (sorted on the names) with the M6811 opcode table
515 (from opcode library). */
519 char *prev_name
= "";
520 struct m68hc11_opcode
*opcodes
;
521 struct m68hc11_opcode_def
*opc
= 0;
524 get_default_target ();
526 m68hc11_hash
= hash_new ();
528 /* Get a writable copy of the opcode table and sort it on the names. */
529 opcodes
= (struct m68hc11_opcode
*) xmalloc (m68hc11_num_opcodes
*
532 m68hc11_sorted_opcodes
= opcodes
;
534 for (i
= 0; i
< m68hc11_num_opcodes
; i
++)
536 if (m68hc11_opcodes
[i
].arch
& current_architecture
)
538 opcodes
[num_opcodes
] = m68hc11_opcodes
[i
];
539 if (opcodes
[num_opcodes
].name
[0] == 'b'
540 && opcodes
[num_opcodes
].format
& M6811_OP_JUMP_REL
541 && !(opcodes
[num_opcodes
].format
& M6811_OP_BITMASK
))
544 opcodes
[num_opcodes
] = m68hc11_opcodes
[i
];
547 for (j
= 0; alias_opcodes
[j
].name
!= 0; j
++)
548 if (strcmp (m68hc11_opcodes
[i
].name
, alias_opcodes
[j
].name
) == 0)
550 opcodes
[num_opcodes
] = m68hc11_opcodes
[i
];
551 opcodes
[num_opcodes
].name
= alias_opcodes
[j
].alias
;
557 qsort (opcodes
, num_opcodes
, sizeof (struct m68hc11_opcode
), cmp_opcode
);
559 opc
= (struct m68hc11_opcode_def
*)
560 xmalloc (num_opcodes
* sizeof (struct m68hc11_opcode_def
));
561 m68hc11_opcode_defs
= opc
--;
563 /* Insert unique names into hash table. The M6811 instruction set
564 has several identical opcode names that have different opcodes based
565 on the operands. This hash table then provides a quick index to
566 the first opcode with a particular name in the opcode table. */
567 for (i
= 0; i
< num_opcodes
; i
++, opcodes
++)
571 if (strcmp (prev_name
, opcodes
->name
))
573 prev_name
= (char *) opcodes
->name
;
577 opc
->min_operands
= 100;
578 opc
->max_operands
= 0;
580 opc
->opcode
= opcodes
;
582 hash_insert (m68hc11_hash
, opcodes
->name
, (char *) opc
);
585 opc
->format
|= opcodes
->format
;
587 /* See how many operands this opcode needs. */
589 if (opcodes
->format
& M6811_OP_MASK
)
591 if (opcodes
->format
& M6811_OP_BITMASK
)
593 if (opcodes
->format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
595 if (opcodes
->format
& (M6812_OP_IND16_P2
| M6812_OP_IDX_P2
))
598 if (expect
< opc
->min_operands
)
599 opc
->min_operands
= expect
;
600 if (expect
> opc
->max_operands
)
601 opc
->max_operands
= expect
;
604 m68hc11_nb_opcode_defs
= opc
- m68hc11_opcode_defs
;
606 if (flag_print_opcodes
)
608 print_opcode_list ();
614 m68hc11_init_after_args ()
620 /* Return a string that represents the operand format for the instruction.
621 When example is true, this generates an example of operand. This is used
622 to give an example and also to generate a test. */
624 print_opcode_format (opcode
, example
)
625 struct m68hc11_opcode
*opcode
;
628 static char buf
[128];
629 int format
= opcode
->format
;
634 if (format
& M6811_OP_IMM8
)
637 sprintf (p
, "#%d", rand () & 0x0FF);
639 strcpy (p
, _("#<imm8>"));
643 if (format
& M6811_OP_IMM16
)
646 sprintf (p
, "#%d", rand () & 0x0FFFF);
648 strcpy (p
, _("#<imm16>"));
652 if (format
& M6811_OP_IX
)
655 sprintf (p
, "%d,X", rand () & 0x0FF);
657 strcpy (p
, _("<imm8>,X"));
661 if (format
& M6811_OP_IY
)
664 sprintf (p
, "%d,X", rand () & 0x0FF);
666 strcpy (p
, _("<imm8>,X"));
670 if (format
& M6812_OP_IDX
)
673 sprintf (p
, "%d,X", rand () & 0x0FF);
679 if (format
& M6811_OP_DIRECT
)
682 sprintf (p
, "*Z%d", rand () & 0x0FF);
684 strcpy (p
, _("*<abs8>"));
688 if (format
& M6811_OP_BITMASK
)
694 sprintf (p
, "#$%02x", rand () & 0x0FF);
696 strcpy (p
, _("#<mask>"));
699 if (format
& M6811_OP_JUMP_REL
)
703 if (format
& M6811_OP_IND16
)
706 sprintf (p
, _("symbol%d"), rand () & 0x0FF);
708 strcpy (p
, _("<abs>"));
713 if (format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
717 if (format
& M6811_OP_BITMASK
)
719 sprintf (p
, ".+%d", rand () & 0x7F);
723 sprintf (p
, "L%d", rand () & 0x0FF);
727 strcpy (p
, _("<label>"));
733 /* Prints the list of instructions with the possible operands. */
738 char *prev_name
= "";
739 struct m68hc11_opcode
*opcodes
;
740 int example
= flag_print_opcodes
== 2;
743 printf (_("# Example of `%s' instructions\n\t.sect .text\n_start:\n"),
746 opcodes
= m68hc11_sorted_opcodes
;
748 /* Walk the list sorted on names (by md_begin). We only report
749 one instruction per line, and we collect the different operand
751 for (i
= 0; i
< num_opcodes
; i
++, opcodes
++)
753 char *fmt
= print_opcode_format (opcodes
, example
);
757 printf ("L%d:\t", i
);
758 printf ("%s %s\n", opcodes
->name
, fmt
);
762 if (strcmp (prev_name
, opcodes
->name
))
767 printf ("%-5.5s ", opcodes
->name
);
768 prev_name
= (char *) opcodes
->name
;
771 printf (" [%s]", fmt
);
777 /* Print the instruction format. This operation is called when some
778 instruction is not correct. Instruction format is printed as an
781 print_insn_format (name
)
784 struct m68hc11_opcode_def
*opc
;
785 struct m68hc11_opcode
*opcode
;
788 opc
= (struct m68hc11_opcode_def
*) hash_find (m68hc11_hash
, name
);
791 as_bad (_("Instruction `%s' is not recognized."), name
);
794 opcode
= opc
->opcode
;
796 as_bad (_("Instruction formats for `%s':"), name
);
801 fmt
= print_opcode_format (opcode
, 0, 0);
802 sprintf (buf
, "\t%-5.5s %s", opcode
->name
, fmt
);
807 while (strcmp (opcode
->name
, name
) == 0);
810 /* Analysis of 68HC11 and 68HC12 operands. */
812 /* reg_name_search() finds the register number given its name.
813 Returns the register number or REG_NONE on failure. */
815 reg_name_search (name
)
818 if (strcasecmp (name
, "x") == 0 || strcasecmp (name
, "ix") == 0)
820 if (strcasecmp (name
, "y") == 0 || strcasecmp (name
, "iy") == 0)
822 if (strcasecmp (name
, "a") == 0)
824 if (strcasecmp (name
, "b") == 0)
826 if (strcasecmp (name
, "d") == 0)
828 if (strcasecmp (name
, "sp") == 0)
830 if (strcasecmp (name
, "pc") == 0)
832 if (strcasecmp (name
, "ccr") == 0)
842 while (*p
== ' ' || *p
== '\t')
848 /* Check the string at input_line_pointer
849 to see if it is a valid register name. */
853 register_id reg_number
;
854 char c
, *p
= input_line_pointer
;
856 if (!is_name_beginner (*p
++))
859 while (is_part_of_name (*p
++))
866 /* Look to see if it's in the register table. */
867 reg_number
= reg_name_search (input_line_pointer
);
868 if (reg_number
!= REG_NONE
)
873 input_line_pointer
= p
;
882 /* Parse a string of operands and return an array of expressions.
884 Operand mode[0] mode[1] exp[0] exp[1]
885 #n M6811_OP_IMM16 - O_*
886 *<exp> M6811_OP_DIRECT - O_*
887 .{+-}<exp> M6811_OP_JUMP_REL - O_*
888 <exp> M6811_OP_IND16 - O_*
889 ,r N,r M6812_OP_IDX M6812_OP_REG O_constant O_register
890 n,-r M6812_PRE_DEC M6812_OP_REG O_constant O_register
891 n,+r M6812_PRE_INC " "
892 n,r- M6812_POST_DEC " "
893 n,r+ M6812_POST_INC " "
894 A,r B,r D,r M6811_OP_REG M6812_OP_REG O_register O_register
895 [D,r] M6811_OP_IDX_2 M6812_OP_REG O_register O_register
896 [n,r] M6811_OP_IDX_1 M6812_OP_REG O_constant O_register */
898 get_operand (oper
, which
, opmode
)
903 char *p
= input_line_pointer
;
907 oper
->exp
.X_op
= O_absent
;
908 oper
->reg1
= REG_NONE
;
909 oper
->reg2
= REG_NONE
;
910 mode
= M6811_OP_NONE
;
914 if (*p
== 0 || *p
== '\n' || *p
== '\r')
916 input_line_pointer
= p
;
920 if (*p
== '*' && (opmode
& (M6811_OP_DIRECT
| M6811_OP_IND16
)))
922 mode
= M6811_OP_DIRECT
;
927 if (!(opmode
& (M6811_OP_IMM8
| M6811_OP_IMM16
| M6811_OP_BITMASK
)))
929 as_bad (_("Immediate operand is not allowed for operand %d."),
934 mode
= M6811_OP_IMM16
;
936 if (strncmp (p
, "%hi", 3) == 0)
939 mode
|= M6811_OP_HIGH_ADDR
;
941 else if (strncmp (p
, "%lo", 3) == 0)
944 mode
|= M6811_OP_LOW_ADDR
;
947 else if (*p
== '.' && (p
[1] == '+' || p
[1] == '-'))
950 mode
= M6811_OP_JUMP_REL
;
954 if (current_architecture
& cpu6811
)
955 as_bad (_("Indirect indexed addressing is not valid for 68HC11."));
958 mode
= M6812_OP_IDX_2
;
961 else if (*p
== ',') /* Special handling of ,x and ,y. */
964 input_line_pointer
= p
;
966 reg
= register_name ();
970 oper
->exp
.X_op
= O_constant
;
971 oper
->exp
.X_add_number
= 0;
972 oper
->mode
= M6812_OP_IDX
;
975 as_bad (_("Spurious `,' or bad indirect register addressing mode."));
978 input_line_pointer
= p
;
980 if (mode
== M6811_OP_NONE
|| mode
== M6812_OP_IDX_2
)
981 reg
= register_name ();
987 p
= skip_whites (input_line_pointer
);
988 if (*p
== ']' && mode
== M6812_OP_IDX_2
)
991 (_("Missing second register or offset for indexed-indirect mode."));
996 oper
->mode
= mode
| M6812_OP_REG
;
999 if (mode
== M6812_OP_IDX_2
)
1001 as_bad (_("Missing second register for indexed-indirect mode."));
1008 input_line_pointer
= p
;
1009 reg
= register_name ();
1010 if (reg
!= REG_NONE
)
1012 p
= skip_whites (input_line_pointer
);
1013 if (mode
== M6812_OP_IDX_2
)
1017 as_bad (_("Missing `]' to close indexed-indirect mode."));
1022 input_line_pointer
= p
;
1030 /* In MRI mode, isolate the operand because we can't distinguish
1031 operands from comments. */
1036 p
= skip_whites (p
);
1037 while (*p
&& *p
!= ' ' && *p
!= '\t')
1046 /* Parse as an expression. */
1047 expression (&oper
->exp
);
1056 expression (&oper
->exp
);
1059 if (oper
->exp
.X_op
== O_illegal
)
1061 as_bad (_("Illegal operand."));
1064 else if (oper
->exp
.X_op
== O_absent
)
1066 as_bad (_("Missing operand."));
1070 p
= input_line_pointer
;
1072 if (mode
== M6811_OP_NONE
|| mode
== M6811_OP_DIRECT
1073 || mode
== M6812_OP_IDX_2
)
1075 p
= skip_whites (input_line_pointer
);
1079 int possible_mode
= M6811_OP_NONE
;
1080 char *old_input_line
;
1083 /* 68HC12 pre increment or decrement. */
1084 if (mode
== M6811_OP_NONE
)
1088 possible_mode
= M6812_PRE_DEC
;
1093 possible_mode
= M6812_PRE_INC
;
1096 p
= skip_whites (p
);
1098 old_input_line
= input_line_pointer
;
1099 input_line_pointer
= p
;
1100 reg
= register_name ();
1102 /* Backtrack if we have a valid constant expression and
1103 it does not correspond to the offset of the 68HC12 indexed
1104 addressing mode (as in N,x). */
1105 if (reg
== REG_NONE
&& mode
== M6811_OP_NONE
1106 && possible_mode
!= M6811_OP_NONE
)
1108 oper
->mode
= M6811_OP_IND16
| M6811_OP_JUMP_REL
;
1109 input_line_pointer
= skip_whites (old_input_line
);
1113 if (possible_mode
!= M6811_OP_NONE
)
1114 mode
= possible_mode
;
1116 if ((current_architecture
& cpu6811
)
1117 && possible_mode
!= M6811_OP_NONE
)
1118 as_bad (_("Pre-increment mode is not valid for 68HC11"));
1120 if (which
== 0 && opmode
& M6812_OP_IDX_P2
1121 && reg
!= REG_X
&& reg
!= REG_Y
1122 && reg
!= REG_PC
&& reg
!= REG_SP
)
1125 input_line_pointer
= p
;
1128 if (reg
== REG_NONE
&& mode
!= M6811_OP_DIRECT
1129 && !(mode
== M6811_OP_NONE
&& opmode
& M6811_OP_IND16
))
1131 as_bad (_("Wrong register in register indirect mode."));
1134 if (mode
== M6812_OP_IDX_2
)
1136 p
= skip_whites (input_line_pointer
);
1139 as_bad (_("Missing `]' to close register indirect operand."));
1142 input_line_pointer
= p
;
1144 if (reg
!= REG_NONE
)
1147 if (mode
== M6811_OP_NONE
)
1149 p
= input_line_pointer
;
1152 mode
= M6812_POST_DEC
;
1154 if (current_architecture
& cpu6811
)
1156 (_("Post-decrement mode is not valid for 68HC11."));
1160 mode
= M6812_POST_INC
;
1162 if (current_architecture
& cpu6811
)
1164 (_("Post-increment mode is not valid for 68HC11."));
1167 mode
= M6812_OP_IDX
;
1169 input_line_pointer
= p
;
1172 mode
|= M6812_OP_IDX
;
1179 if (mode
== M6812_OP_D_IDX_2
)
1181 as_bad (_("Invalid indexed indirect mode."));
1186 /* If the mode is not known until now, this is either a label
1187 or an indirect address. */
1188 if (mode
== M6811_OP_NONE
)
1189 mode
= M6811_OP_IND16
| M6811_OP_JUMP_REL
;
1191 p
= input_line_pointer
;
1192 while (*p
== ' ' || *p
== '\t')
1194 input_line_pointer
= p
;
1200 #define M6812_AUTO_INC_DEC (M6812_PRE_INC | M6812_PRE_DEC \
1201 | M6812_POST_INC | M6812_POST_DEC)
1203 /* Checks that the number 'num' fits for a given mode. */
1205 check_range (num
, mode
)
1209 /* Auto increment and decrement are ok for [-8..8] without 0. */
1210 if (mode
& M6812_AUTO_INC_DEC
)
1211 return (num
!= 0 && num
<= 8 && num
>= -8);
1213 /* The 68HC12 supports 5, 9 and 16-bit offsets. */
1214 if (mode
& (M6812_INDEXED_IND
| M6812_INDEXED
| M6812_OP_IDX
))
1215 mode
= M6811_OP_IND16
;
1217 if (mode
& M6812_OP_JUMP_REL16
)
1218 mode
= M6811_OP_IND16
;
1224 case M6811_OP_DIRECT
:
1225 return (num
>= 0 && num
<= 255) ? 1 : 0;
1227 case M6811_OP_BITMASK
:
1229 return (((num
& 0xFFFFFF00) == 0) || ((num
& 0xFFFFFF00) == 0xFFFFFF00))
1232 case M6811_OP_JUMP_REL
:
1233 return (num
>= -128 && num
<= 127) ? 1 : 0;
1235 case M6811_OP_IND16
:
1236 case M6811_OP_IMM16
:
1237 return (((num
& 0xFFFF0000) == 0) || ((num
& 0xFFFF0000) == 0xFFFF0000))
1240 case M6812_OP_IBCC_MARKER
:
1241 case M6812_OP_TBCC_MARKER
:
1242 case M6812_OP_DBCC_MARKER
:
1243 return (num
>= -256 && num
<= 255) ? 1 : 0;
1245 case M6812_OP_TRAP_ID
:
1246 return ((num
>= 0x30 && num
<= 0x39)
1247 || (num
>= 0x40 && num
<= 0x0ff)) ? 1 : 0;
1254 /* Gas fixup generation. */
1256 /* Put a 1 byte expression described by 'oper'. If this expression contains
1257 unresolved symbols, generate an 8-bit fixup. */
1259 fixup8 (oper
, mode
, opmode
)
1268 if (oper
->X_op
== O_constant
)
1270 if (mode
& M6812_OP_TRAP_ID
1271 && !check_range (oper
->X_add_number
, M6812_OP_TRAP_ID
))
1273 static char trap_id_warn_once
= 0;
1275 as_bad (_("Trap id `%ld' is out of range."), oper
->X_add_number
);
1276 if (trap_id_warn_once
== 0)
1278 trap_id_warn_once
= 1;
1279 as_bad (_("Trap id must be within [0x30..0x39] or [0x40..0xff]."));
1283 if (!(mode
& M6812_OP_TRAP_ID
)
1284 && !check_range (oper
->X_add_number
, mode
))
1286 as_bad (_("Operand out of 8-bit range: `%ld'."), oper
->X_add_number
);
1288 number_to_chars_bigendian (f
, oper
->X_add_number
& 0x0FF, 1);
1290 else if (oper
->X_op
!= O_register
)
1292 if (mode
& M6812_OP_TRAP_ID
)
1293 as_bad (_("The trap id must be a constant."));
1295 if (mode
== M6811_OP_JUMP_REL
)
1299 fixp
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 1,
1300 oper
, true, BFD_RELOC_8_PCREL
);
1301 fixp
->fx_pcrel_adjust
= 1;
1305 /* Now create an 8-bit fixup. If there was some %hi or %lo
1306 modifier, generate the reloc accordingly. */
1307 fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 1,
1309 ((opmode
& M6811_OP_HIGH_ADDR
)
1310 ? BFD_RELOC_M68HC11_HI8
1311 : ((opmode
& M6811_OP_LOW_ADDR
)
1312 ? BFD_RELOC_M68HC11_LO8
: BFD_RELOC_8
)));
1314 number_to_chars_bigendian (f
, 0, 1);
1318 as_fatal (_("Operand `%x' not recognized in fixup8."), oper
->X_op
);
1322 /* Put a 2 byte expression described by 'oper'. If this expression contains
1323 unresolved symbols, generate a 16-bit fixup. */
1325 fixup16 (oper
, mode
, opmode
)
1328 int opmode ATTRIBUTE_UNUSED
;
1334 if (oper
->X_op
== O_constant
)
1336 if (!check_range (oper
->X_add_number
, mode
))
1338 as_bad (_("Operand out of 16-bit range: `%ld'."),
1339 oper
->X_add_number
);
1341 number_to_chars_bigendian (f
, oper
->X_add_number
& 0x0FFFF, 2);
1343 else if (oper
->X_op
!= O_register
)
1347 /* Now create a 16-bit fixup. */
1348 fixp
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 2,
1350 (mode
& M6812_OP_JUMP_REL16
? true : false),
1351 (mode
& M6812_OP_JUMP_REL16
1352 ? BFD_RELOC_16_PCREL
: BFD_RELOC_16
));
1353 number_to_chars_bigendian (f
, 0, 2);
1354 if (mode
& M6812_OP_JUMP_REL16
)
1355 fixp
->fx_pcrel_adjust
= 2;
1359 as_fatal (_("Operand `%x' not recognized in fixup16."), oper
->X_op
);
1363 /* 68HC11 and 68HC12 code generation. */
1365 /* Translate the short branch/bsr instruction into a long branch. */
1366 static unsigned char
1367 convert_branch (code
)
1370 if (IS_OPCODE (code
, M6812_BSR
))
1372 else if (IS_OPCODE (code
, M6811_BSR
))
1374 else if (IS_OPCODE (code
, M6811_BRA
))
1375 return (current_architecture
& cpu6812
) ? M6812_JMP
: M6811_JMP
;
1377 as_fatal (_("Unexpected branch conversion with `%x'"), code
);
1379 /* Keep gcc happy. */
1383 /* Start a new insn that contains at least 'size' bytes. Record the
1384 line information of that insn in the dwarf2 debug sections. */
1386 m68hc11_new_insn (size
)
1391 f
= frag_more (size
);
1393 dwarf2_emit_insn (size
);
1398 /* Builds a jump instruction (bra, bcc, bsr). */
1400 build_jump_insn (opcode
, operands
, nb_operands
, jmp_mode
)
1401 struct m68hc11_opcode
*opcode
;
1410 /* The relative branch convertion is not supported for
1412 assert ((opcode
->format
& M6811_OP_BITMASK
) == 0);
1413 assert (nb_operands
== 1);
1414 assert (operands
[0].reg1
== REG_NONE
&& operands
[0].reg2
== REG_NONE
);
1416 code
= opcode
->opcode
;
1418 n
= operands
[0].exp
.X_add_number
;
1420 /* Turn into a long branch:
1421 - when force long branch option (and not for jbcc pseudos),
1422 - when jbcc and the constant is out of -128..127 range,
1423 - when branch optimization is allowed and branch out of range. */
1424 if ((jmp_mode
== 0 && flag_force_long_jumps
)
1425 || (operands
[0].exp
.X_op
== O_constant
1426 && (!check_range (n
, opcode
->format
) &&
1427 (jmp_mode
== 1 || flag_fixed_branchs
== 0))))
1429 if (code
== M6811_BSR
|| code
== M6811_BRA
|| code
== M6812_BSR
)
1431 code
= convert_branch (code
);
1433 f
= m68hc11_new_insn (1);
1434 number_to_chars_bigendian (f
, code
, 1);
1436 else if (current_architecture
& cpu6812
)
1438 /* 68HC12: translate the bcc into a lbcc. */
1439 f
= m68hc11_new_insn (2);
1440 number_to_chars_bigendian (f
, M6811_OPCODE_PAGE2
, 1);
1441 number_to_chars_bigendian (f
+ 1, code
, 1);
1442 fixup16 (&operands
[0].exp
, M6812_OP_JUMP_REL16
,
1443 M6812_OP_JUMP_REL16
);
1448 /* 68HC11: translate the bcc into b!cc +3; jmp <L>. */
1449 f
= m68hc11_new_insn (3);
1451 number_to_chars_bigendian (f
, code
, 1);
1452 number_to_chars_bigendian (f
+ 1, 3, 1);
1453 number_to_chars_bigendian (f
+ 2, M6811_JMP
, 1);
1455 fixup16 (&operands
[0].exp
, M6811_OP_IND16
, M6811_OP_IND16
);
1459 /* Branch with a constant that must fit in 8-bits. */
1460 if (operands
[0].exp
.X_op
== O_constant
)
1462 if (!check_range (n
, opcode
->format
))
1464 as_bad (_("Operand out of range for a relative branch: `%ld'"),
1467 else if (opcode
->format
& M6812_OP_JUMP_REL16
)
1469 f
= m68hc11_new_insn (4);
1470 number_to_chars_bigendian (f
, M6811_OPCODE_PAGE2
, 1);
1471 number_to_chars_bigendian (f
+ 1, code
, 1);
1472 number_to_chars_bigendian (f
+ 2, n
& 0x0ffff, 2);
1476 f
= m68hc11_new_insn (2);
1477 number_to_chars_bigendian (f
, code
, 1);
1478 number_to_chars_bigendian (f
+ 1, n
& 0x0FF, 1);
1481 else if (opcode
->format
& M6812_OP_JUMP_REL16
)
1483 f
= m68hc11_new_insn (2);
1484 number_to_chars_bigendian (f
, M6811_OPCODE_PAGE2
, 1);
1485 number_to_chars_bigendian (f
+ 1, code
, 1);
1486 fixup16 (&operands
[0].exp
, M6812_OP_JUMP_REL16
, M6812_OP_JUMP_REL16
);
1492 /* Branch offset must fit in 8-bits, don't do some relax. */
1493 if (jmp_mode
== 0 && flag_fixed_branchs
)
1495 opcode
= m68hc11_new_insn (1);
1496 number_to_chars_bigendian (opcode
, code
, 1);
1497 fixup8 (&operands
[0].exp
, M6811_OP_JUMP_REL
, M6811_OP_JUMP_REL
);
1500 /* bra/bsr made be changed into jmp/jsr. */
1501 else if (code
== M6811_BSR
|| code
== M6811_BRA
|| code
== M6812_BSR
)
1503 opcode
= m68hc11_new_insn (2);
1504 number_to_chars_bigendian (opcode
, code
, 1);
1505 number_to_chars_bigendian (opcode
+ 1, 0, 1);
1506 frag_var (rs_machine_dependent
, 2, 1,
1507 ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_UNDF
),
1508 operands
[0].exp
.X_add_symbol
, (offsetT
) n
, opcode
);
1510 else if (current_architecture
& cpu6812
)
1512 opcode
= m68hc11_new_insn (2);
1513 number_to_chars_bigendian (opcode
, code
, 1);
1514 number_to_chars_bigendian (opcode
+ 1, 0, 1);
1515 frag_var (rs_machine_dependent
, 2, 2,
1516 ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
, STATE_UNDF
),
1517 operands
[0].exp
.X_add_symbol
, (offsetT
) n
, opcode
);
1521 opcode
= m68hc11_new_insn (2);
1522 number_to_chars_bigendian (opcode
, code
, 1);
1523 number_to_chars_bigendian (opcode
+ 1, 0, 1);
1524 frag_var (rs_machine_dependent
, 3, 3,
1525 ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
, STATE_UNDF
),
1526 operands
[0].exp
.X_add_symbol
, (offsetT
) n
, opcode
);
1531 /* Builds a dbne/dbeq/tbne/tbeq instruction. */
1533 build_dbranch_insn (opcode
, operands
, nb_operands
, jmp_mode
)
1534 struct m68hc11_opcode
*opcode
;
1543 /* The relative branch convertion is not supported for
1545 assert ((opcode
->format
& M6811_OP_BITMASK
) == 0);
1546 assert (nb_operands
== 2);
1547 assert (operands
[0].reg1
!= REG_NONE
);
1549 code
= opcode
->opcode
& 0x0FF;
1551 f
= m68hc11_new_insn (1);
1552 number_to_chars_bigendian (f
, code
, 1);
1554 n
= operands
[1].exp
.X_add_number
;
1555 code
= operands
[0].reg1
;
1557 if (operands
[0].reg1
== REG_NONE
|| operands
[0].reg1
== REG_CCR
1558 || operands
[0].reg1
== REG_PC
)
1559 as_bad (_("Invalid register for dbcc/tbcc instruction."));
1561 if (opcode
->format
& M6812_OP_IBCC_MARKER
)
1563 else if (opcode
->format
& M6812_OP_TBCC_MARKER
)
1566 if (!(opcode
->format
& M6812_OP_EQ_MARKER
))
1569 /* Turn into a long branch:
1570 - when force long branch option (and not for jbcc pseudos),
1571 - when jdbcc and the constant is out of -256..255 range,
1572 - when branch optimization is allowed and branch out of range. */
1573 if ((jmp_mode
== 0 && flag_force_long_jumps
)
1574 || (operands
[1].exp
.X_op
== O_constant
1575 && (!check_range (n
, M6812_OP_IBCC_MARKER
) &&
1576 (jmp_mode
== 1 || flag_fixed_branchs
== 0))))
1580 number_to_chars_bigendian (f
, code
, 1);
1581 number_to_chars_bigendian (f
+ 1, M6812_JMP
, 1);
1582 fixup16 (&operands
[0].exp
, M6811_OP_IND16
, M6811_OP_IND16
);
1586 /* Branch with a constant that must fit in 9-bits. */
1587 if (operands
[1].exp
.X_op
== O_constant
)
1589 if (!check_range (n
, M6812_OP_IBCC_MARKER
))
1591 as_bad (_("Operand out of range for a relative branch: `%ld'"),
1600 number_to_chars_bigendian (f
, code
, 1);
1601 number_to_chars_bigendian (f
+ 1, n
& 0x0FF, 1);
1606 /* Branch offset must fit in 8-bits, don't do some relax. */
1607 if (jmp_mode
== 0 && flag_fixed_branchs
)
1609 fixup8 (&operands
[0].exp
, M6811_OP_JUMP_REL
, M6811_OP_JUMP_REL
);
1615 number_to_chars_bigendian (f
, code
, 1);
1616 number_to_chars_bigendian (f
+ 1, 0, 1);
1617 frag_var (rs_machine_dependent
, 3, 3,
1618 ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_UNDF
),
1619 operands
[1].exp
.X_add_symbol
, (offsetT
) n
, f
);
1624 #define OP_EXTENDED (M6811_OP_PAGE2 | M6811_OP_PAGE3 | M6811_OP_PAGE4)
1626 /* Assemble the post index byte for 68HC12 extended addressing modes. */
1628 build_indexed_byte (op
, format
, move_insn
)
1630 int format ATTRIBUTE_UNUSED
;
1633 unsigned char byte
= 0;
1638 val
= op
->exp
.X_add_number
;
1640 if (mode
& M6812_AUTO_INC_DEC
)
1643 if (mode
& (M6812_POST_INC
| M6812_POST_DEC
))
1646 if (op
->exp
.X_op
== O_constant
)
1648 if (!check_range (val
, mode
))
1650 as_bad (_("Increment/decrement value is out of range: `%ld'."),
1653 if (mode
& (M6812_POST_INC
| M6812_PRE_INC
))
1654 byte
|= (val
- 1) & 0x07;
1656 byte
|= (8 - ((val
) & 7)) | 0x8;
1661 as_fatal (_("Expecting a register."));
1676 as_bad (_("Invalid register for post/pre increment."));
1681 number_to_chars_bigendian (f
, byte
, 1);
1685 if (mode
& M6812_OP_IDX
)
1706 as_bad (_("Invalid register."));
1709 if (op
->exp
.X_op
== O_constant
)
1711 if (!check_range (val
, M6812_OP_IDX
))
1713 as_bad (_("Offset out of 16-bit range: %ld."), val
);
1716 if (move_insn
&& !(val
>= -16 && val
<= 15))
1718 as_bad (_("Offset out of 5-bit range for movw/movb insn: %ld."),
1723 if (val
>= -16 && val
<= 15 && !(mode
& M6812_OP_IDX_2
))
1728 number_to_chars_bigendian (f
, byte
, 1);
1731 else if (val
>= -256 && val
<= 255 && !(mode
& M6812_OP_IDX_2
))
1738 number_to_chars_bigendian (f
, byte
, 1);
1739 number_to_chars_bigendian (f
+ 1, val
& 0x0FF, 1);
1745 if (mode
& M6812_OP_IDX_2
)
1751 number_to_chars_bigendian (f
, byte
, 1);
1752 number_to_chars_bigendian (f
+ 1, val
& 0x0FFFF, 2);
1756 if (op
->reg1
!= REG_PC
)
1758 byte
= (byte
<< 3) | 0xe2;
1760 number_to_chars_bigendian (f
, byte
, 1);
1763 fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 2,
1764 &op
->exp
, false, BFD_RELOC_16
);
1765 number_to_chars_bigendian (f
, 0, 2);
1770 number_to_chars_bigendian (f
, byte
, 1);
1771 frag_var (rs_machine_dependent
, 2, 2,
1772 ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_UNDF
),
1773 op
->exp
.X_add_symbol
,
1774 op
->exp
.X_add_number
, f
);
1779 if (mode
& M6812_OP_REG
)
1781 if (mode
& M6812_OP_IDX_2
)
1783 if (op
->reg1
!= REG_D
)
1784 as_bad (_("Expecting register D for indexed indirect mode."));
1786 as_bad (_("Indexed indirect mode is not allowed for movb/movw."));
1803 as_bad (_("Invalid accumulator register."));
1828 as_bad (_("Invalid indexed register."));
1832 number_to_chars_bigendian (f
, byte
, 1);
1836 as_fatal (_("Addressing mode not implemented yet."));
1840 /* Assemble the 68HC12 register mode byte. */
1842 build_reg_mode (op
, format
)
1849 if (format
& M6812_OP_SEX_MARKER
1850 && op
->reg1
!= REG_A
&& op
->reg1
!= REG_B
&& op
->reg1
!= REG_CCR
)
1851 as_bad (_("Invalid source register for this instruction, use 'tfr'."));
1852 else if (op
->reg1
== REG_NONE
|| op
->reg1
== REG_PC
)
1853 as_bad (_("Invalid source register."));
1855 if (format
& M6812_OP_SEX_MARKER
1856 && op
->reg2
!= REG_D
1857 && op
->reg2
!= REG_X
&& op
->reg2
!= REG_Y
&& op
->reg2
!= REG_SP
)
1858 as_bad (_("Invalid destination register for this instruction, use 'tfr'."));
1859 else if (op
->reg2
== REG_NONE
|| op
->reg2
== REG_PC
)
1860 as_bad (_("Invalid destination register."));
1862 byte
= (op
->reg1
<< 4) | (op
->reg2
);
1863 if (format
& M6812_OP_EXG_MARKER
)
1867 number_to_chars_bigendian (f
, byte
, 1);
1871 /* build_insn takes a pointer to the opcode entry in the opcode table,
1872 the array of operand expressions and builds the correspding instruction.
1873 This operation only deals with non relative jumps insn (need special
1876 build_insn (opcode
, operands
, nb_operands
)
1877 struct m68hc11_opcode
*opcode
;
1879 int nb_operands ATTRIBUTE_UNUSED
;
1886 /* Put the page code instruction if there is one. */
1887 format
= opcode
->format
;
1888 if (format
& OP_EXTENDED
)
1892 f
= m68hc11_new_insn (2);
1893 if (format
& M6811_OP_PAGE2
)
1894 page_code
= M6811_OPCODE_PAGE2
;
1895 else if (format
& M6811_OP_PAGE3
)
1896 page_code
= M6811_OPCODE_PAGE3
;
1898 page_code
= M6811_OPCODE_PAGE4
;
1900 number_to_chars_bigendian (f
, page_code
, 1);
1904 f
= m68hc11_new_insn (1);
1906 number_to_chars_bigendian (f
, opcode
->opcode
, 1);
1910 /* The 68HC12 movb and movw instructions are special. We have to handle
1911 them in a special way. */
1912 if (format
& (M6812_OP_IND16_P2
| M6812_OP_IDX_P2
))
1915 if (format
& M6812_OP_IDX
)
1917 build_indexed_byte (&operands
[0], format
, 1);
1919 format
&= ~M6812_OP_IDX
;
1921 if (format
& M6812_OP_IDX_P2
)
1923 build_indexed_byte (&operands
[1], format
, 1);
1925 format
&= ~M6812_OP_IDX_P2
;
1929 if (format
& (M6811_OP_DIRECT
| M6811_OP_IMM8
))
1931 fixup8 (&operands
[i
].exp
,
1932 format
& (M6811_OP_DIRECT
| M6811_OP_IMM8
| M6812_OP_TRAP_ID
),
1936 else if (format
& (M6811_OP_IMM16
| M6811_OP_IND16
))
1938 fixup16 (&operands
[i
].exp
, format
& (M6811_OP_IMM16
| M6811_OP_IND16
),
1942 else if (format
& (M6811_OP_IX
| M6811_OP_IY
))
1944 if ((format
& M6811_OP_IX
) && (operands
[0].reg1
!= REG_X
))
1945 as_bad (_("Invalid indexed register, expecting register X."));
1946 if ((format
& M6811_OP_IY
) && (operands
[0].reg1
!= REG_Y
))
1947 as_bad (_("Invalid indexed register, expecting register Y."));
1949 fixup8 (&operands
[0].exp
, M6811_OP_IX
, operands
[0].mode
);
1953 (M6812_OP_IDX
| M6812_OP_IDX_2
| M6812_OP_IDX_1
| M6812_OP_D_IDX
))
1955 build_indexed_byte (&operands
[i
], format
, move_insn
);
1958 else if (format
& M6812_OP_REG
&& current_architecture
& cpu6812
)
1960 build_reg_mode (&operands
[i
], format
);
1963 if (format
& M6811_OP_BITMASK
)
1965 fixup8 (&operands
[i
].exp
, M6811_OP_BITMASK
, operands
[i
].mode
);
1968 if (format
& M6811_OP_JUMP_REL
)
1970 fixup8 (&operands
[i
].exp
, M6811_OP_JUMP_REL
, operands
[i
].mode
);
1972 else if (format
& M6812_OP_IND16_P2
)
1974 fixup16 (&operands
[1].exp
, M6811_OP_IND16
, operands
[1].mode
);
1978 /* Opcode identification and operand analysis. */
1980 /* find() gets a pointer to an entry in the opcode table. It must look at all
1981 opcodes with the same name and use the operands to choose the correct
1982 opcode. Returns the opcode pointer if there was a match and 0 if none. */
1983 static struct m68hc11_opcode
*
1984 find (opc
, operands
, nb_operands
)
1985 struct m68hc11_opcode_def
*opc
;
1990 struct m68hc11_opcode
*opcode
;
1991 struct m68hc11_opcode
*op_indirect
;
1994 opcode
= opc
->opcode
;
1996 /* Now search the opcode table table for one with operands
1997 that matches what we've got. We're only done if the operands matched so
1998 far AND there are no more to check. */
1999 for (pos
= match
= 0; match
== 0 && pos
< opc
->nb_modes
; pos
++, opcode
++)
2001 int poss_indirect
= 0;
2002 long format
= opcode
->format
;
2006 if (opcode
->format
& M6811_OP_MASK
)
2008 if (opcode
->format
& M6811_OP_BITMASK
)
2010 if (opcode
->format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
2012 if (opcode
->format
& (M6812_OP_IND16_P2
| M6812_OP_IDX_P2
))
2015 for (i
= 0; expect
== nb_operands
&& i
< nb_operands
; i
++)
2017 int mode
= operands
[i
].mode
;
2019 if (mode
& M6811_OP_IMM16
)
2022 (M6811_OP_IMM8
| M6811_OP_IMM16
| M6811_OP_BITMASK
))
2026 if (mode
== M6811_OP_DIRECT
)
2028 if (format
& M6811_OP_DIRECT
)
2031 /* If the operand is a page 0 operand, remember a
2032 possible <abs-16> addressing mode. We mark
2033 this and continue to check other operands. */
2034 if (format
& M6811_OP_IND16
2035 && flag_strict_direct_addressing
&& op_indirect
== 0)
2042 if (mode
& M6811_OP_IND16
)
2044 if (i
== 0 && (format
& M6811_OP_IND16
) != 0)
2046 if (i
!= 0 && (format
& M6812_OP_IND16_P2
) != 0)
2048 if (i
== 0 && (format
& M6811_OP_BITMASK
))
2051 if (mode
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
2053 if (format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
2056 if (mode
& M6812_OP_REG
)
2059 && (format
& M6812_OP_REG
)
2060 && (operands
[i
].reg2
== REG_NONE
))
2063 && (format
& M6812_OP_REG
)
2064 && (format
& M6812_OP_REG_2
)
2065 && (operands
[i
].reg2
!= REG_NONE
))
2068 && (format
& M6812_OP_IDX
)
2069 && (operands
[i
].reg2
!= REG_NONE
))
2072 && (format
& M6812_OP_D_IDX
))
2075 && (format
& M6812_OP_IDX
)
2076 && (format
& (M6812_OP_IND16_P2
| M6812_OP_IDX_P2
)))
2079 && (format
& M6812_OP_IDX_P2
))
2083 if (mode
& M6812_OP_IDX
)
2085 if (format
& M6811_OP_IX
&& operands
[i
].reg1
== REG_X
)
2087 if (format
& M6811_OP_IY
&& operands
[i
].reg1
== REG_Y
)
2090 && format
& (M6812_OP_IDX
| M6812_OP_IDX_1
| M6812_OP_IDX_2
)
2091 && (operands
[i
].reg1
== REG_X
2092 || operands
[i
].reg1
== REG_Y
2093 || operands
[i
].reg1
== REG_SP
2094 || operands
[i
].reg1
== REG_PC
))
2096 if (i
== 1 && format
& M6812_OP_IDX_P2
)
2099 if (mode
& M6812_AUTO_INC_DEC
)
2102 && format
& (M6812_OP_IDX
| M6812_OP_IDX_1
|
2105 if (i
== 1 && format
& M6812_OP_IDX_P2
)
2110 match
= i
== nb_operands
;
2112 /* Operands are ok but an operand uses page 0 addressing mode
2113 while the insn supports abs-16 mode. Keep a reference to this
2114 insns in case there is no insn supporting page 0 addressing. */
2115 if (match
&& poss_indirect
)
2117 op_indirect
= opcode
;
2124 /* Page 0 addressing is used but not supported by any insn.
2125 If absolute addresses are supported, we use that insn. */
2126 if (match
== 0 && op_indirect
)
2128 opcode
= op_indirect
;
2140 /* Find the real opcode and its associated operands. We use a progressive
2141 approach here. On entry, 'opc' points to the first opcode in the
2142 table that matches the opcode name in the source line. We try to
2143 isolate an operand, find a possible match in the opcode table.
2144 We isolate another operand if no match were found. The table 'operands'
2145 is filled while operands are recognized.
2147 Returns the opcode pointer that matches the opcode name in the
2148 source line and the associated operands. */
2149 static struct m68hc11_opcode
*
2150 find_opcode (opc
, operands
, nb_operands
)
2151 struct m68hc11_opcode_def
*opc
;
2155 struct m68hc11_opcode
*opcode
;
2158 if (opc
->max_operands
== 0)
2164 for (i
= 0; i
< opc
->max_operands
;)
2168 result
= get_operand (&operands
[i
], i
, opc
->format
);
2172 /* Special case where the bitmask of the bclr/brclr
2173 instructions is not introduced by #.
2174 Example: bclr 3,x $80. */
2175 if (i
== 1 && (opc
->format
& M6811_OP_BITMASK
)
2176 && (operands
[i
].mode
& M6811_OP_IND16
))
2178 operands
[i
].mode
= M6811_OP_IMM16
;
2183 if (i
>= opc
->min_operands
)
2185 opcode
= find (opc
, operands
, i
);
2190 if (*input_line_pointer
== ',')
2191 input_line_pointer
++;
2197 #define M6812_XBCC_MARKER (M6812_OP_TBCC_MARKER \
2198 | M6812_OP_DBCC_MARKER \
2199 | M6812_OP_IBCC_MARKER)
2201 /* Gas line assembler entry point. */
2203 /* This is the main entry point for the machine-dependent assembler. str
2204 points to a machine-dependent instruction. This function is supposed to
2205 emit the frags/bytes it assembles to. */
2210 struct m68hc11_opcode_def
*opc
;
2211 struct m68hc11_opcode
*opcode
;
2213 unsigned char *op_start
, *save
;
2214 unsigned char *op_end
;
2217 operand operands
[M6811_MAX_OPERANDS
];
2219 int branch_optimize
= 0;
2222 /* Drop leading whitespace. */
2226 /* Find the opcode end and get the opcode in 'name'. The opcode is forced
2227 lower case (the opcode table only has lower case op-codes). */
2228 for (op_start
= op_end
= (unsigned char *) (str
);
2229 *op_end
&& nlen
< 20 && !is_end_of_line
[*op_end
] && *op_end
!= ' ';
2232 name
[nlen
] = tolower (op_start
[nlen
]);
2239 as_bad (_("No instruction or missing opcode."));
2243 /* Find the opcode definition given its name. */
2244 opc
= (struct m68hc11_opcode_def
*) hash_find (m68hc11_hash
, name
);
2246 /* If it's not recognized, look for 'jbsr' and 'jbxx'. These are
2247 pseudo insns for relative branch. For these branchs, we always
2248 optimize them (turned into absolute branchs) even if --short-branchs
2250 if (opc
== NULL
&& name
[0] == 'j' && name
[1] == 'b')
2252 opc
= (struct m68hc11_opcode_def
*) hash_find (m68hc11_hash
, &name
[1]);
2254 && (!(opc
->format
& M6811_OP_JUMP_REL
)
2255 || (opc
->format
& M6811_OP_BITMASK
)))
2258 branch_optimize
= 1;
2261 /* The following test should probably be removed. This is not conform
2262 to Motorola assembler specs. */
2263 if (opc
== NULL
&& flag_mri
)
2265 if (*op_end
== ' ' || *op_end
== '\t')
2267 while (*op_end
== ' ' || *op_end
== '\t')
2272 (is_end_of_line
[op_end
[1]]
2273 || op_end
[1] == ' ' || op_end
[1] == '\t'
2274 || !isalnum (op_end
[1])))
2275 && (*op_end
== 'a' || *op_end
== 'b'
2276 || *op_end
== 'A' || *op_end
== 'B'
2277 || *op_end
== 'd' || *op_end
== 'D'
2278 || *op_end
== 'x' || *op_end
== 'X'
2279 || *op_end
== 'y' || *op_end
== 'Y'))
2281 name
[nlen
++] = tolower (*op_end
++);
2283 opc
= (struct m68hc11_opcode_def
*) hash_find (m68hc11_hash
,
2289 /* Identify a possible instruction alias. There are some on the
2290 68HC12 to emulate a few 68HC11 instructions. */
2291 if (opc
== NULL
&& (current_architecture
& cpu6812
))
2295 for (i
= 0; i
< m68hc12_num_alias
; i
++)
2296 if (strcmp (m68hc12_alias
[i
].name
, name
) == 0)
2302 if (opc
== NULL
&& alias_id
< 0)
2304 as_bad (_("Opcode `%s' is not recognized."), name
);
2307 save
= input_line_pointer
;
2308 input_line_pointer
= op_end
;
2313 opcode
= find_opcode (opc
, operands
, &nb_operands
);
2318 if ((opcode
|| alias_id
>= 0) && !flag_mri
)
2320 char *p
= input_line_pointer
;
2322 while (*p
== ' ' || *p
== '\t' || *p
== '\n' || *p
== '\r')
2325 if (*p
!= '\n' && *p
)
2326 as_bad (_("Garbage at end of instruction: `%s'."), p
);
2329 input_line_pointer
= save
;
2333 char *f
= m68hc11_new_insn (m68hc12_alias
[alias_id
].size
);
2335 number_to_chars_bigendian (f
, m68hc12_alias
[alias_id
].code1
, 1);
2336 if (m68hc12_alias
[alias_id
].size
> 1)
2337 number_to_chars_bigendian (f
+ 1, m68hc12_alias
[alias_id
].code2
, 1);
2342 /* Opcode is known but does not have valid operands. Print out the
2343 syntax for this opcode. */
2346 if (flag_print_insn_syntax
)
2347 print_insn_format (name
);
2349 as_bad (_("Invalid operand for `%s'"), name
);
2353 /* Treat dbeq/ibeq/tbeq instructions in a special way. The branch is
2354 relative and must be in the range -256..255 (9-bits). */
2355 if ((opcode
->format
& M6812_XBCC_MARKER
)
2356 && (opcode
->format
& M6811_OP_JUMP_REL
))
2357 build_dbranch_insn (opcode
, operands
, nb_operands
);
2359 /* Relative jumps instructions are taken care of separately. We have to make
2360 sure that the relative branch is within the range -128..127. If it's out
2361 of range, the instructions are changed into absolute instructions.
2362 This is not supported for the brset and brclr instructions. */
2363 else if ((opcode
->format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
2364 && !(opcode
->format
& M6811_OP_BITMASK
))
2365 build_jump_insn (opcode
, operands
, nb_operands
, branch_optimize
);
2367 build_insn (opcode
, operands
, nb_operands
);
2370 /* Relocation, relaxation and frag conversions. */
2372 md_pcrel_from_section (fixp
, sec
)
2377 if (fixp
->fx_addsy
!= (symbolS
*) NULL
2378 && (!S_IS_DEFINED (fixp
->fx_addsy
)
2379 || (S_GET_SEGMENT (fixp
->fx_addsy
) != sec
)))
2382 adjust
= fixp
->fx_pcrel_adjust
;
2383 return fixp
->fx_frag
->fr_address
+ fixp
->fx_where
+ adjust
;
2386 /* If while processing a fixup, a reloc really needs to be created
2387 then it is done here. */
2389 tc_gen_reloc (section
, fixp
)
2395 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
2396 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
2397 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
2398 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
2399 if (fixp
->fx_r_type
== 0)
2400 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_16
);
2402 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
2403 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
2405 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2406 _("Relocation %d is not supported by object file format."),
2407 (int) fixp
->fx_r_type
);
2411 if (!fixp
->fx_pcrel
)
2412 reloc
->addend
= fixp
->fx_addnumber
;
2414 reloc
->addend
= (section
->vma
2415 + (fixp
->fx_pcrel_adjust
== 64
2416 ? -1 : fixp
->fx_pcrel_adjust
)
2417 + fixp
->fx_addnumber
2418 + md_pcrel_from_section (fixp
, section
));
2423 md_convert_frag (abfd
, sec
, fragP
)
2424 bfd
*abfd ATTRIBUTE_UNUSED
;
2425 asection
*sec ATTRIBUTE_UNUSED
;
2431 char *buffer_address
= fragP
->fr_literal
;
2433 /* Address in object code of the displacement. */
2434 register int object_address
= fragP
->fr_fix
+ fragP
->fr_address
;
2436 buffer_address
+= fragP
->fr_fix
;
2438 /* The displacement of the address, from current location. */
2439 value
= fragP
->fr_symbol
? S_GET_VALUE (fragP
->fr_symbol
) : 0;
2440 disp
= (value
+ fragP
->fr_offset
) - object_address
;
2441 disp
+= symbol_get_frag (fragP
->fr_symbol
)->fr_address
;
2443 switch (fragP
->fr_subtype
)
2445 case ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_BYTE
):
2446 fragP
->fr_opcode
[1] = disp
;
2449 case ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_WORD
):
2450 /* This relax is only for bsr and bra. */
2451 assert (IS_OPCODE (fragP
->fr_opcode
[0], M6811_BSR
)
2452 || IS_OPCODE (fragP
->fr_opcode
[0], M6811_BRA
)
2453 || IS_OPCODE (fragP
->fr_opcode
[0], M6812_BSR
));
2455 fragP
->fr_opcode
[0] = convert_branch (fragP
->fr_opcode
[0]);
2457 fix_new (fragP
, fragP
->fr_fix
- 1, 2,
2458 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_16
);
2462 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
, STATE_BYTE
):
2463 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
, STATE_BYTE
):
2464 fragP
->fr_opcode
[1] = disp
;
2467 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
, STATE_WORD
):
2468 /* Invert branch. */
2469 fragP
->fr_opcode
[0] ^= 1;
2470 fragP
->fr_opcode
[1] = 3; /* Branch offset. */
2471 buffer_address
[0] = M6811_JMP
;
2472 fix_new (fragP
, fragP
->fr_fix
+ 1, 2,
2473 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_16
);
2477 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
, STATE_WORD
):
2478 /* Translate branch into a long branch. */
2479 fragP
->fr_opcode
[1] = fragP
->fr_opcode
[0];
2480 fragP
->fr_opcode
[0] = M6811_OPCODE_PAGE2
;
2482 fixp
= fix_new (fragP
, fragP
->fr_fix
, 2,
2483 fragP
->fr_symbol
, fragP
->fr_offset
, 1,
2484 BFD_RELOC_16_PCREL
);
2485 fixp
->fx_pcrel_adjust
= 2;
2489 case ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS5
):
2490 fragP
->fr_opcode
[0] = fragP
->fr_opcode
[0] << 6;
2491 if ((fragP
->fr_opcode
[0] & 0x0ff) == 0x0c0)
2492 fragP
->fr_opcode
[0] |= disp
& 0x1f;
2494 fragP
->fr_opcode
[0] |= value
& 0x1f;
2497 case ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS9
):
2498 fragP
->fr_opcode
[0] = (fragP
->fr_opcode
[0] << 3);
2499 fragP
->fr_opcode
[0] |= 0xE0;
2500 fix_new (fragP
, fragP
->fr_fix
, 1,
2501 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_8
);
2505 case ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS16
):
2506 fragP
->fr_opcode
[0] = (fragP
->fr_opcode
[0] << 3);
2507 fragP
->fr_opcode
[0] |= 0xe2;
2508 if ((fragP
->fr_opcode
[0] & 0x0ff) == 0x0fa)
2510 fixp
= fix_new (fragP
, fragP
->fr_fix
, 2,
2511 fragP
->fr_symbol
, fragP
->fr_offset
,
2512 1, BFD_RELOC_16_PCREL
);
2513 fixp
->fx_pcrel_adjust
= 2;
2517 fix_new (fragP
, fragP
->fr_fix
, 2,
2518 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_16
);
2523 case ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_BYTE
):
2525 fragP
->fr_opcode
[0] |= 0x10;
2527 fragP
->fr_opcode
[1] = disp
& 0x0FF;
2530 case ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_WORD
):
2531 /* Invert branch. */
2532 fragP
->fr_opcode
[0] ^= 0x20;
2533 fragP
->fr_opcode
[1] = 3; /* Branch offset. */
2534 buffer_address
[0] = M6812_JMP
;
2535 fix_new (fragP
, fragP
->fr_fix
+ 1, 2,
2536 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_16
);
2545 /* On an ELF system, we can't relax a weak symbol. The weak symbol
2546 can be overridden at final link time by a non weak symbol. We can
2547 relax externally visible symbol because there is no shared library
2548 and such symbol can't be overridden (unless they are weak). */
2550 relaxable_symbol (symbol
)
2553 return ! 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
);