1 /* tc-m68hc11.c -- Assembler code for the Motorola 68HC11 & 68HC12.
2 Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
3 Written by Stephane Carrez (stcarrez@worldnet.fr)
5 This file is part of GAS, the GNU Assembler.
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
26 #include "opcode/m68hc11.h"
27 #include "dwarf2dbg.h"
29 const char comment_chars
[] = ";!";
30 const char line_comment_chars
[] = "#*";
31 const char line_separator_chars
[] = "";
33 const char EXP_CHARS
[] = "eE";
34 const char FLT_CHARS
[] = "dD";
36 #define STATE_CONDITIONAL_BRANCH (1)
37 #define STATE_PC_RELATIVE (2)
38 #define STATE_INDEXED_OFFSET (3)
39 #define STATE_XBCC_BRANCH (4)
40 #define STATE_CONDITIONAL_BRANCH_6812 (5)
42 #define STATE_BYTE (0)
43 #define STATE_BITS5 (0)
44 #define STATE_WORD (1)
45 #define STATE_BITS9 (1)
46 #define STATE_LONG (2)
47 #define STATE_BITS16 (2)
48 #define STATE_UNDF (3) /* Symbol undefined in pass1 */
50 /* This macro has no side-effects. */
51 #define ENCODE_RELAX(what,length) (((what) << 2) + (length))
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},
235 {"xrefb", s_ignore
, 0}, /* Same as xref */
240 /* Options and initialization. */
242 CONST
char *md_shortopts
= "Sm:";
244 struct option md_longopts
[] = {
245 #define OPTION_FORCE_LONG_BRANCH (OPTION_MD_BASE)
246 {"force-long-branchs", no_argument
, NULL
, OPTION_FORCE_LONG_BRANCH
},
248 #define OPTION_SHORT_BRANCHS (OPTION_MD_BASE + 1)
249 {"short-branchs", no_argument
, NULL
, OPTION_SHORT_BRANCHS
},
251 #define OPTION_STRICT_DIRECT_MODE (OPTION_MD_BASE + 2)
252 {"strict-direct-mode", no_argument
, NULL
, OPTION_STRICT_DIRECT_MODE
},
254 #define OPTION_PRINT_INSN_SYNTAX (OPTION_MD_BASE + 3)
255 {"print-insn-syntax", no_argument
, NULL
, OPTION_PRINT_INSN_SYNTAX
},
257 #define OPTION_PRINT_OPCODES (OPTION_MD_BASE + 4)
258 {"print-opcodes", no_argument
, NULL
, OPTION_PRINT_OPCODES
},
260 #define OPTION_GENERATE_EXAMPLE (OPTION_MD_BASE + 5)
261 {"generate-example", no_argument
, NULL
, OPTION_GENERATE_EXAMPLE
},
263 {NULL
, no_argument
, NULL
, 0}
265 size_t md_longopts_size
= sizeof (md_longopts
);
267 /* Get the target cpu for the assembler. This is based on the configure
268 options and on the -m68hc11/-m68hc12 option. If no option is specified,
269 we must get the default. */
271 m68hc11_arch_format ()
273 get_default_target ();
274 if (current_architecture
& cpu6811
)
275 return "elf32-m68hc11";
277 return "elf32-m68hc12";
280 enum bfd_architecture
283 get_default_target ();
284 if (current_architecture
& cpu6811
)
285 return bfd_arch_m68hc11
;
287 return bfd_arch_m68hc12
;
296 /* Listing header selected according to cpu. */
298 m68hc11_listing_header ()
300 if (current_architecture
& cpu6811
)
301 return "M68HC11 GAS ";
303 return "M68HC12 GAS ";
307 md_show_usage (stream
)
310 get_default_target ();
311 fprintf (stream
, _("\
312 Motorola 68HC11/68HC12 options:\n\
313 -m68hc11 | -m68hc12 specify the processor [default %s]\n\
314 --force-long-branchs always turn relative branchs into absolute ones\n\
315 -S,--short-branchs do not turn relative branchs into absolute ones\n\
316 when the offset is out of range\n\
317 --strict-direct-mode do not turn the direct mode into extended mode\n\
318 when the instruction does not support direct mode\n\
319 --print-insn-syntax print the syntax of instruction in case of error\n\
320 --print-opcodes print the list of instructions with syntax\n\
321 --generate-example generate an example of each instruction\n\
322 (used for testing)\n"), default_cpu
);
326 /* Try to identify the default target based on the BFD library. */
328 get_default_target ()
330 const bfd_target
*target
;
333 if (current_architecture
!= 0)
336 default_cpu
= "unknown";
337 target
= bfd_find_target (0, &abfd
);
338 if (target
&& target
->name
)
340 if (strcmp (target
->name
, "elf32-m68hc12") == 0)
342 current_architecture
= cpu6812
;
343 default_cpu
= "m68hc12";
345 else if (strcmp (target
->name
, "elf32-m68hc11") == 0)
347 current_architecture
= cpu6811
;
348 default_cpu
= "m68hc11";
352 as_bad (_("Default target `%s' is not supported."), target
->name
);
358 m68hc11_print_statistics (file
)
362 struct m68hc11_opcode_def
*opc
;
364 hash_print_statistics (file
, "opcode table", m68hc11_hash
);
366 opc
= m68hc11_opcode_defs
;
367 if (opc
== 0 || m68hc11_nb_opcode_defs
== 0)
370 /* Dump the opcode statistics table. */
371 fprintf (file
, _("Name # Modes Min ops Max ops Modes mask # Used\n"));
372 for (i
= 0; i
< m68hc11_nb_opcode_defs
; i
++, opc
++)
374 fprintf (file
, "%-7.7s %5d %7d %7d 0x%08lx %7d\n",
377 opc
->min_operands
, opc
->max_operands
, opc
->format
, opc
->used
);
382 md_parse_option (c
, arg
)
386 get_default_target ();
389 /* -S means keep external to 2 bit offset rather than 16 bit one. */
390 case OPTION_SHORT_BRANCHS
:
392 flag_fixed_branchs
= 1;
395 case OPTION_FORCE_LONG_BRANCH
:
396 flag_force_long_jumps
= 1;
399 case OPTION_PRINT_INSN_SYNTAX
:
400 flag_print_insn_syntax
= 1;
403 case OPTION_PRINT_OPCODES
:
404 flag_print_opcodes
= 1;
407 case OPTION_STRICT_DIRECT_MODE
:
408 flag_strict_direct_addressing
= 0;
411 case OPTION_GENERATE_EXAMPLE
:
412 flag_print_opcodes
= 2;
416 if (strcasecmp (arg
, "68hc11") == 0)
417 current_architecture
= cpu6811
;
418 else if (strcasecmp (arg
, "68hc12") == 0)
419 current_architecture
= cpu6812
;
421 as_bad (_("Option `%s' is not recognized."), arg
);
432 md_undefined_symbol (name
)
433 char *name ATTRIBUTE_UNUSED
;
438 /* Equal to MAX_PRECISION in atof-ieee.c. */
439 #define MAX_LITTLENUMS 6
441 /* Turn a string in input_line_pointer into a floating point constant
442 of type TYPE, and store the appropriate bytes in *LITP. The number
443 of LITTLENUMS emitted is stored in *SIZEP. An error message is
444 returned, or NULL on OK. */
446 md_atof (type
, litP
, sizeP
)
452 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
453 LITTLENUM_TYPE
*wordP
;
484 return _("Bad call to MD_ATOF()");
486 t
= atof_ieee (input_line_pointer
, type
, words
);
488 input_line_pointer
= t
;
490 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
491 for (wordP
= words
; prec
--;)
493 md_number_to_chars (litP
, (long) (*wordP
++), sizeof (LITTLENUM_TYPE
));
494 litP
+= sizeof (LITTLENUM_TYPE
);
500 md_section_align (seg
, addr
)
504 int align
= bfd_get_section_alignment (stdoutput
, seg
);
505 return ((addr
+ (1 << align
) - 1) & (-1 << align
));
509 cmp_opcode (op1
, op2
)
510 struct m68hc11_opcode
*op1
;
511 struct m68hc11_opcode
*op2
;
513 return strcmp (op1
->name
, op2
->name
);
516 /* Initialize the assembler. Create the opcode hash table
517 (sorted on the names) with the M6811 opcode table
518 (from opcode library). */
522 char *prev_name
= "";
523 struct m68hc11_opcode
*opcodes
;
524 struct m68hc11_opcode_def
*opc
= 0;
527 get_default_target ();
529 m68hc11_hash
= hash_new ();
531 /* Get a writable copy of the opcode table and sort it on the names. */
532 opcodes
= (struct m68hc11_opcode
*) xmalloc (m68hc11_num_opcodes
*
535 m68hc11_sorted_opcodes
= opcodes
;
537 for (i
= 0; i
< m68hc11_num_opcodes
; i
++)
539 if (m68hc11_opcodes
[i
].arch
& current_architecture
)
541 opcodes
[num_opcodes
] = m68hc11_opcodes
[i
];
542 if (opcodes
[num_opcodes
].name
[0] == 'b'
543 && opcodes
[num_opcodes
].format
& M6811_OP_JUMP_REL
544 && !(opcodes
[num_opcodes
].format
& M6811_OP_BITMASK
))
547 opcodes
[num_opcodes
] = m68hc11_opcodes
[i
];
550 for (j
= 0; alias_opcodes
[j
].name
!= 0; j
++)
551 if (strcmp (m68hc11_opcodes
[i
].name
, alias_opcodes
[j
].name
) == 0)
553 opcodes
[num_opcodes
] = m68hc11_opcodes
[i
];
554 opcodes
[num_opcodes
].name
= alias_opcodes
[j
].alias
;
560 qsort (opcodes
, num_opcodes
, sizeof (struct m68hc11_opcode
), cmp_opcode
);
562 opc
= (struct m68hc11_opcode_def
*)
563 xmalloc (num_opcodes
* sizeof (struct m68hc11_opcode_def
));
564 m68hc11_opcode_defs
= opc
--;
566 /* Insert unique names into hash table. The M6811 instruction set
567 has several identical opcode names that have different opcodes based
568 on the operands. This hash table then provides a quick index to
569 the first opcode with a particular name in the opcode table. */
570 for (i
= 0; i
< num_opcodes
; i
++, opcodes
++)
574 if (strcmp (prev_name
, opcodes
->name
))
576 prev_name
= (char *) opcodes
->name
;
580 opc
->min_operands
= 100;
581 opc
->max_operands
= 0;
583 opc
->opcode
= opcodes
;
585 hash_insert (m68hc11_hash
, opcodes
->name
, (char *) opc
);
588 opc
->format
|= opcodes
->format
;
590 /* See how many operands this opcode needs. */
592 if (opcodes
->format
& M6811_OP_MASK
)
594 if (opcodes
->format
& M6811_OP_BITMASK
)
596 if (opcodes
->format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
598 if (opcodes
->format
& (M6812_OP_IND16_P2
| M6812_OP_IDX_P2
))
601 if (expect
< opc
->min_operands
)
602 opc
->min_operands
= expect
;
603 if (expect
> opc
->max_operands
)
604 opc
->max_operands
= expect
;
607 m68hc11_nb_opcode_defs
= opc
- m68hc11_opcode_defs
;
609 if (flag_print_opcodes
)
611 print_opcode_list ();
617 m68hc11_init_after_args ()
623 /* Return a string that represents the operand format for the instruction.
624 When example is true, this generates an example of operand. This is used
625 to give an example and also to generate a test. */
627 print_opcode_format (opcode
, example
)
628 struct m68hc11_opcode
*opcode
;
631 static char buf
[128];
632 int format
= opcode
->format
;
637 if (format
& M6811_OP_IMM8
)
640 sprintf (p
, "#%d", rand () & 0x0FF);
642 strcpy (p
, _("#<imm8>"));
646 if (format
& M6811_OP_IMM16
)
649 sprintf (p
, "#%d", rand () & 0x0FFFF);
651 strcpy (p
, _("#<imm16>"));
655 if (format
& M6811_OP_IX
)
658 sprintf (p
, "%d,X", rand () & 0x0FF);
660 strcpy (p
, _("<imm8>,X"));
664 if (format
& M6811_OP_IY
)
667 sprintf (p
, "%d,X", rand () & 0x0FF);
669 strcpy (p
, _("<imm8>,X"));
673 if (format
& M6812_OP_IDX
)
676 sprintf (p
, "%d,X", rand () & 0x0FF);
682 if (format
& M6811_OP_DIRECT
)
685 sprintf (p
, "*Z%d", rand () & 0x0FF);
687 strcpy (p
, _("*<abs8>"));
691 if (format
& M6811_OP_BITMASK
)
697 sprintf (p
, "#$%02x", rand () & 0x0FF);
699 strcpy (p
, _("#<mask>"));
702 if (format
& M6811_OP_JUMP_REL
)
706 if (format
& M6811_OP_IND16
)
709 sprintf (p
, _("symbol%d"), rand () & 0x0FF);
711 strcpy (p
, _("<abs>"));
716 if (format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
720 if (format
& M6811_OP_BITMASK
)
722 sprintf (p
, ".+%d", rand () & 0x7F);
726 sprintf (p
, "L%d", rand () & 0x0FF);
730 strcpy (p
, _("<label>"));
736 /* Prints the list of instructions with the possible operands. */
741 char *prev_name
= "";
742 struct m68hc11_opcode
*opcodes
;
743 int example
= flag_print_opcodes
== 2;
746 printf (_("# Example of `%s' instructions\n\t.sect .text\n_start:\n"),
749 opcodes
= m68hc11_sorted_opcodes
;
751 /* Walk the list sorted on names (by md_begin). We only report
752 one instruction per line, and we collect the different operand
754 for (i
= 0; i
< num_opcodes
; i
++, opcodes
++)
756 char *fmt
= print_opcode_format (opcodes
, example
);
760 printf ("L%d:\t", i
);
761 printf ("%s %s\n", opcodes
->name
, fmt
);
765 if (strcmp (prev_name
, opcodes
->name
))
770 printf ("%-5.5s ", opcodes
->name
);
771 prev_name
= (char *) opcodes
->name
;
774 printf (" [%s]", fmt
);
780 /* Print the instruction format. This operation is called when some
781 instruction is not correct. Instruction format is printed as an
784 print_insn_format (name
)
787 struct m68hc11_opcode_def
*opc
;
788 struct m68hc11_opcode
*opcode
;
791 opc
= (struct m68hc11_opcode_def
*) hash_find (m68hc11_hash
, name
);
794 as_bad (_("Instruction `%s' is not recognized."), name
);
797 opcode
= opc
->opcode
;
799 as_bad (_("Instruction formats for `%s':"), name
);
804 fmt
= print_opcode_format (opcode
, 0, 0);
805 sprintf (buf
, "\t%-5.5s %s", opcode
->name
, fmt
);
810 while (strcmp (opcode
->name
, name
) == 0);
813 /* Analysis of 68HC11 and 68HC12 operands. */
815 /* reg_name_search() finds the register number given its name.
816 Returns the register number or REG_NONE on failure. */
818 reg_name_search (name
)
821 if (strcasecmp (name
, "x") == 0 || strcasecmp (name
, "ix") == 0)
823 if (strcasecmp (name
, "y") == 0 || strcasecmp (name
, "iy") == 0)
825 if (strcasecmp (name
, "a") == 0)
827 if (strcasecmp (name
, "b") == 0)
829 if (strcasecmp (name
, "d") == 0)
831 if (strcasecmp (name
, "sp") == 0)
833 if (strcasecmp (name
, "pc") == 0)
835 if (strcasecmp (name
, "ccr") == 0)
845 while (*p
== ' ' || *p
== '\t')
851 /* Check the string at input_line_pointer
852 to see if it is a valid register name. */
856 register_id reg_number
;
857 char c
, *p
= input_line_pointer
;
859 if (!is_name_beginner (*p
++))
862 while (is_part_of_name (*p
++))
869 /* Look to see if it's in the register table. */
870 reg_number
= reg_name_search (input_line_pointer
);
871 if (reg_number
!= REG_NONE
)
876 input_line_pointer
= p
;
885 /* Parse a string of operands and return an array of expressions.
887 Operand mode[0] mode[1] exp[0] exp[1]
888 #n M6811_OP_IMM16 - O_*
889 *<exp> M6811_OP_DIRECT - O_*
890 .{+-}<exp> M6811_OP_JUMP_REL - O_*
891 <exp> M6811_OP_IND16 - O_*
892 ,r N,r M6812_OP_IDX M6812_OP_REG O_constant O_register
893 n,-r M6812_PRE_DEC M6812_OP_REG O_constant O_register
894 n,+r M6812_PRE_INC " "
895 n,r- M6812_POST_DEC " "
896 n,r+ M6812_POST_INC " "
897 A,r B,r D,r M6811_OP_REG M6812_OP_REG O_register O_register
898 [D,r] M6811_OP_IDX_2 M6812_OP_REG O_register O_register
899 [n,r] M6811_OP_IDX_1 M6812_OP_REG O_constant O_register */
901 get_operand (oper
, which
, opmode
)
906 char *p
= input_line_pointer
;
910 oper
->exp
.X_op
= O_absent
;
911 oper
->reg1
= REG_NONE
;
912 oper
->reg2
= REG_NONE
;
913 mode
= M6811_OP_NONE
;
917 if (*p
== 0 || *p
== '\n' || *p
== '\r')
919 input_line_pointer
= p
;
923 if (*p
== '*' && (opmode
& (M6811_OP_DIRECT
| M6811_OP_IND16
)))
925 mode
= M6811_OP_DIRECT
;
930 if (!(opmode
& (M6811_OP_IMM8
| M6811_OP_IMM16
| M6811_OP_BITMASK
)))
932 as_bad (_("Immediate operand is not allowed for operand %d."),
937 mode
= M6811_OP_IMM16
;
939 if (strncmp (p
, "%hi", 3) == 0)
942 mode
|= M6811_OP_HIGH_ADDR
;
944 else if (strncmp (p
, "%lo", 3) == 0)
947 mode
|= M6811_OP_LOW_ADDR
;
950 else if (*p
== '.' && (p
[1] == '+' || p
[1] == '-'))
953 mode
= M6811_OP_JUMP_REL
;
957 if (current_architecture
& cpu6811
)
958 as_bad (_("Indirect indexed addressing is not valid for 68HC11."));
961 mode
= M6812_OP_IDX_2
;
964 else if (*p
== ',') /* Special handling of ,x and ,y. */
967 input_line_pointer
= p
;
969 reg
= register_name ();
973 oper
->exp
.X_op
= O_constant
;
974 oper
->exp
.X_add_number
= 0;
975 oper
->mode
= M6812_OP_IDX
;
978 as_bad (_("Spurious `,' or bad indirect register addressing mode."));
981 input_line_pointer
= p
;
983 if (mode
== M6811_OP_NONE
|| mode
== M6812_OP_IDX_2
)
984 reg
= register_name ();
990 p
= skip_whites (input_line_pointer
);
991 if (*p
== ']' && mode
== M6812_OP_IDX_2
)
994 (_("Missing second register or offset for indexed-indirect mode."));
999 oper
->mode
= mode
| M6812_OP_REG
;
1002 if (mode
== M6812_OP_IDX_2
)
1004 as_bad (_("Missing second register for indexed-indirect mode."));
1011 input_line_pointer
= p
;
1012 reg
= register_name ();
1013 if (reg
!= REG_NONE
)
1015 p
= skip_whites (input_line_pointer
);
1016 if (mode
== M6812_OP_IDX_2
)
1020 as_bad (_("Missing `]' to close indexed-indirect mode."));
1025 input_line_pointer
= p
;
1033 /* In MRI mode, isolate the operand because we can't distinguish
1034 operands from comments. */
1039 p
= skip_whites (p
);
1040 while (*p
&& *p
!= ' ' && *p
!= '\t')
1049 /* Parse as an expression. */
1050 expression (&oper
->exp
);
1059 expression (&oper
->exp
);
1062 if (oper
->exp
.X_op
== O_illegal
)
1064 as_bad (_("Illegal operand."));
1067 else if (oper
->exp
.X_op
== O_absent
)
1069 as_bad (_("Missing operand."));
1073 p
= input_line_pointer
;
1075 if (mode
== M6811_OP_NONE
|| mode
== M6811_OP_DIRECT
1076 || mode
== M6812_OP_IDX_2
)
1078 p
= skip_whites (input_line_pointer
);
1082 int possible_mode
= M6811_OP_NONE
;
1083 char *old_input_line
;
1086 /* 68HC12 pre increment or decrement. */
1087 if (mode
== M6811_OP_NONE
)
1091 possible_mode
= M6812_PRE_DEC
;
1096 possible_mode
= M6812_PRE_INC
;
1099 p
= skip_whites (p
);
1101 old_input_line
= input_line_pointer
;
1102 input_line_pointer
= p
;
1103 reg
= register_name ();
1105 /* Backtrack if we have a valid constant expression and
1106 it does not correspond to the offset of the 68HC12 indexed
1107 addressing mode (as in N,x). */
1108 if (reg
== REG_NONE
&& mode
== M6811_OP_NONE
1109 && possible_mode
!= M6811_OP_NONE
)
1111 oper
->mode
= M6811_OP_IND16
| M6811_OP_JUMP_REL
;
1112 input_line_pointer
= skip_whites (old_input_line
);
1116 if (possible_mode
!= M6811_OP_NONE
)
1117 mode
= possible_mode
;
1119 if ((current_architecture
& cpu6811
)
1120 && possible_mode
!= M6811_OP_NONE
)
1121 as_bad (_("Pre-increment mode is not valid for 68HC11"));
1123 if (which
== 0 && opmode
& M6812_OP_IDX_P2
1124 && reg
!= REG_X
&& reg
!= REG_Y
1125 && reg
!= REG_PC
&& reg
!= REG_SP
)
1128 input_line_pointer
= p
;
1131 if (reg
== REG_NONE
&& mode
!= M6811_OP_DIRECT
1132 && !(mode
== M6811_OP_NONE
&& opmode
& M6811_OP_IND16
))
1134 as_bad (_("Wrong register in register indirect mode."));
1137 if (mode
== M6812_OP_IDX_2
)
1139 p
= skip_whites (input_line_pointer
);
1142 as_bad (_("Missing `]' to close register indirect operand."));
1145 input_line_pointer
= p
;
1147 if (reg
!= REG_NONE
)
1150 if (mode
== M6811_OP_NONE
)
1152 p
= input_line_pointer
;
1155 mode
= M6812_POST_DEC
;
1157 if (current_architecture
& cpu6811
)
1159 (_("Post-decrement mode is not valid for 68HC11."));
1163 mode
= M6812_POST_INC
;
1165 if (current_architecture
& cpu6811
)
1167 (_("Post-increment mode is not valid for 68HC11."));
1170 mode
= M6812_OP_IDX
;
1172 input_line_pointer
= p
;
1175 mode
|= M6812_OP_IDX
;
1182 if (mode
== M6812_OP_D_IDX_2
)
1184 as_bad (_("Invalid indexed indirect mode."));
1189 /* If the mode is not known until now, this is either a label
1190 or an indirect address. */
1191 if (mode
== M6811_OP_NONE
)
1192 mode
= M6811_OP_IND16
| M6811_OP_JUMP_REL
;
1194 p
= input_line_pointer
;
1195 while (*p
== ' ' || *p
== '\t')
1197 input_line_pointer
= p
;
1203 #define M6812_AUTO_INC_DEC (M6812_PRE_INC | M6812_PRE_DEC \
1204 | M6812_POST_INC | M6812_POST_DEC)
1206 /* Checks that the number 'num' fits for a given mode. */
1208 check_range (num
, mode
)
1212 /* Auto increment and decrement are ok for [-8..8] without 0. */
1213 if (mode
& M6812_AUTO_INC_DEC
)
1214 return (num
!= 0 && num
<= 8 && num
>= -8);
1216 /* The 68HC12 supports 5, 9 and 16-bit offsets. */
1217 if (mode
& (M6812_INDEXED_IND
| M6812_INDEXED
| M6812_OP_IDX
))
1218 mode
= M6811_OP_IND16
;
1220 if (mode
& M6812_OP_JUMP_REL16
)
1221 mode
= M6811_OP_IND16
;
1227 case M6811_OP_DIRECT
:
1228 return (num
>= 0 && num
<= 255) ? 1 : 0;
1230 case M6811_OP_BITMASK
:
1232 return (((num
& 0xFFFFFF00) == 0) || ((num
& 0xFFFFFF00) == 0xFFFFFF00))
1235 case M6811_OP_JUMP_REL
:
1236 return (num
>= -128 && num
<= 127) ? 1 : 0;
1238 case M6811_OP_IND16
:
1239 case M6811_OP_IMM16
:
1240 return (((num
& 0xFFFF0000) == 0) || ((num
& 0xFFFF0000) == 0xFFFF0000))
1243 case M6812_OP_IBCC_MARKER
:
1244 case M6812_OP_TBCC_MARKER
:
1245 case M6812_OP_DBCC_MARKER
:
1246 return (num
>= -256 && num
<= 255) ? 1 : 0;
1248 case M6812_OP_TRAP_ID
:
1249 return ((num
>= 0x30 && num
<= 0x39)
1250 || (num
>= 0x40 && num
<= 0x0ff)) ? 1 : 0;
1257 /* Gas fixup generation. */
1259 /* Put a 1 byte expression described by 'oper'. If this expression contains
1260 unresolved symbols, generate an 8-bit fixup. */
1262 fixup8 (oper
, mode
, opmode
)
1271 if (oper
->X_op
== O_constant
)
1273 if (mode
& M6812_OP_TRAP_ID
1274 && !check_range (oper
->X_add_number
, M6812_OP_TRAP_ID
))
1276 static char trap_id_warn_once
= 0;
1278 as_bad (_("Trap id `%ld' is out of range."), oper
->X_add_number
);
1279 if (trap_id_warn_once
== 0)
1281 trap_id_warn_once
= 1;
1282 as_bad (_("Trap id must be within [0x30..0x39] or [0x40..0xff]."));
1286 if (!(mode
& M6812_OP_TRAP_ID
)
1287 && !check_range (oper
->X_add_number
, mode
))
1289 as_bad (_("Operand out of 8-bit range: `%ld'."), oper
->X_add_number
);
1291 number_to_chars_bigendian (f
, oper
->X_add_number
& 0x0FF, 1);
1293 else if (oper
->X_op
!= O_register
)
1295 if (mode
& M6812_OP_TRAP_ID
)
1296 as_bad (_("The trap id must be a constant."));
1298 if (mode
== M6811_OP_JUMP_REL
)
1302 fixp
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 1,
1303 oper
, true, BFD_RELOC_8_PCREL
);
1304 fixp
->fx_pcrel_adjust
= 1;
1308 /* Now create an 8-bit fixup. If there was some %hi or %lo
1309 modifier, generate the reloc accordingly. */
1310 fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 1,
1312 ((opmode
& M6811_OP_HIGH_ADDR
)
1313 ? BFD_RELOC_M68HC11_HI8
1314 : ((opmode
& M6811_OP_LOW_ADDR
)
1315 ? BFD_RELOC_M68HC11_LO8
: BFD_RELOC_8
)));
1317 number_to_chars_bigendian (f
, 0, 1);
1321 as_fatal (_("Operand `%x' not recognized in fixup8."), oper
->X_op
);
1325 /* Put a 2 byte expression described by 'oper'. If this expression contains
1326 unresolved symbols, generate a 16-bit fixup. */
1328 fixup16 (oper
, mode
, opmode
)
1331 int opmode ATTRIBUTE_UNUSED
;
1337 if (oper
->X_op
== O_constant
)
1339 if (!check_range (oper
->X_add_number
, mode
))
1341 as_bad (_("Operand out of 16-bit range: `%ld'."),
1342 oper
->X_add_number
);
1344 number_to_chars_bigendian (f
, oper
->X_add_number
& 0x0FFFF, 2);
1346 else if (oper
->X_op
!= O_register
)
1350 /* Now create a 16-bit fixup. */
1351 fixp
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 2,
1353 (mode
& M6812_OP_JUMP_REL16
? true : false),
1354 (mode
& M6812_OP_JUMP_REL16
1355 ? BFD_RELOC_16_PCREL
: BFD_RELOC_16
));
1356 number_to_chars_bigendian (f
, 0, 2);
1357 if (mode
& M6812_OP_JUMP_REL16
)
1358 fixp
->fx_pcrel_adjust
= 2;
1362 as_fatal (_("Operand `%x' not recognized in fixup16."), oper
->X_op
);
1366 /* 68HC11 and 68HC12 code generation. */
1368 /* Translate the short branch/bsr instruction into a long branch. */
1369 static unsigned char
1370 convert_branch (code
)
1373 if (IS_OPCODE (code
, M6812_BSR
))
1375 else if (IS_OPCODE (code
, M6811_BSR
))
1377 else if (IS_OPCODE (code
, M6811_BRA
))
1378 return (current_architecture
& cpu6812
) ? M6812_JMP
: M6811_JMP
;
1380 as_fatal (_("Unexpected branch conversion with `%x'"), code
);
1382 /* Keep gcc happy. */
1386 /* Start a new insn that contains at least 'size' bytes. Record the
1387 line information of that insn in the dwarf2 debug sections. */
1389 m68hc11_new_insn (size
)
1394 f
= frag_more (size
);
1396 dwarf2_emit_insn (size
);
1401 /* Builds a jump instruction (bra, bcc, bsr). */
1403 build_jump_insn (opcode
, operands
, nb_operands
, jmp_mode
)
1404 struct m68hc11_opcode
*opcode
;
1413 /* The relative branch convertion is not supported for
1415 assert ((opcode
->format
& M6811_OP_BITMASK
) == 0);
1416 assert (nb_operands
== 1);
1417 assert (operands
[0].reg1
== REG_NONE
&& operands
[0].reg2
== REG_NONE
);
1419 code
= opcode
->opcode
;
1421 n
= operands
[0].exp
.X_add_number
;
1423 /* Turn into a long branch:
1424 - when force long branch option (and not for jbcc pseudos),
1425 - when jbcc and the constant is out of -128..127 range,
1426 - when branch optimization is allowed and branch out of range. */
1427 if ((jmp_mode
== 0 && flag_force_long_jumps
)
1428 || (operands
[0].exp
.X_op
== O_constant
1429 && (!check_range (n
, opcode
->format
) &&
1430 (jmp_mode
== 1 || flag_fixed_branchs
== 0))))
1432 if (code
== M6811_BSR
|| code
== M6811_BRA
|| code
== M6812_BSR
)
1434 code
= convert_branch (code
);
1436 f
= m68hc11_new_insn (1);
1437 number_to_chars_bigendian (f
, code
, 1);
1439 else if (current_architecture
& cpu6812
)
1441 /* 68HC12: translate the bcc into a lbcc. */
1442 f
= m68hc11_new_insn (2);
1443 number_to_chars_bigendian (f
, M6811_OPCODE_PAGE2
, 1);
1444 number_to_chars_bigendian (f
+ 1, code
, 1);
1445 fixup16 (&operands
[0].exp
, M6812_OP_JUMP_REL16
,
1446 M6812_OP_JUMP_REL16
);
1451 /* 68HC11: translate the bcc into b!cc +3; jmp <L>. */
1452 f
= m68hc11_new_insn (3);
1454 number_to_chars_bigendian (f
, code
, 1);
1455 number_to_chars_bigendian (f
+ 1, 3, 1);
1456 number_to_chars_bigendian (f
+ 2, M6811_JMP
, 1);
1458 fixup16 (&operands
[0].exp
, M6811_OP_IND16
, M6811_OP_IND16
);
1462 /* Branch with a constant that must fit in 8-bits. */
1463 if (operands
[0].exp
.X_op
== O_constant
)
1465 if (!check_range (n
, opcode
->format
))
1467 as_bad (_("Operand out of range for a relative branch: `%ld'"),
1470 else if (opcode
->format
& M6812_OP_JUMP_REL16
)
1472 f
= m68hc11_new_insn (4);
1473 number_to_chars_bigendian (f
, M6811_OPCODE_PAGE2
, 1);
1474 number_to_chars_bigendian (f
+ 1, code
, 1);
1475 number_to_chars_bigendian (f
+ 2, n
& 0x0ffff, 2);
1479 f
= m68hc11_new_insn (2);
1480 number_to_chars_bigendian (f
, code
, 1);
1481 number_to_chars_bigendian (f
+ 1, n
& 0x0FF, 1);
1484 else if (opcode
->format
& M6812_OP_JUMP_REL16
)
1486 f
= m68hc11_new_insn (2);
1487 number_to_chars_bigendian (f
, M6811_OPCODE_PAGE2
, 1);
1488 number_to_chars_bigendian (f
+ 1, code
, 1);
1489 fixup16 (&operands
[0].exp
, M6812_OP_JUMP_REL16
, M6812_OP_JUMP_REL16
);
1495 /* Branch offset must fit in 8-bits, don't do some relax. */
1496 if (jmp_mode
== 0 && flag_fixed_branchs
)
1498 opcode
= m68hc11_new_insn (1);
1499 number_to_chars_bigendian (opcode
, code
, 1);
1500 fixup8 (&operands
[0].exp
, M6811_OP_JUMP_REL
, M6811_OP_JUMP_REL
);
1503 /* bra/bsr made be changed into jmp/jsr. */
1504 else if (code
== M6811_BSR
|| code
== M6811_BRA
|| code
== M6812_BSR
)
1506 opcode
= m68hc11_new_insn (2);
1507 number_to_chars_bigendian (opcode
, code
, 1);
1508 number_to_chars_bigendian (opcode
+ 1, 0, 1);
1509 frag_var (rs_machine_dependent
, 2, 1,
1510 ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_UNDF
),
1511 operands
[0].exp
.X_add_symbol
, (offsetT
) n
, opcode
);
1513 else if (current_architecture
& cpu6812
)
1515 opcode
= m68hc11_new_insn (2);
1516 number_to_chars_bigendian (opcode
, code
, 1);
1517 number_to_chars_bigendian (opcode
+ 1, 0, 1);
1518 frag_var (rs_machine_dependent
, 2, 2,
1519 ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
, STATE_UNDF
),
1520 operands
[0].exp
.X_add_symbol
, (offsetT
) n
, opcode
);
1524 opcode
= m68hc11_new_insn (2);
1525 number_to_chars_bigendian (opcode
, code
, 1);
1526 number_to_chars_bigendian (opcode
+ 1, 0, 1);
1527 frag_var (rs_machine_dependent
, 3, 3,
1528 ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
, STATE_UNDF
),
1529 operands
[0].exp
.X_add_symbol
, (offsetT
) n
, opcode
);
1534 /* Builds a dbne/dbeq/tbne/tbeq instruction. */
1536 build_dbranch_insn (opcode
, operands
, nb_operands
, jmp_mode
)
1537 struct m68hc11_opcode
*opcode
;
1546 /* The relative branch convertion is not supported for
1548 assert ((opcode
->format
& M6811_OP_BITMASK
) == 0);
1549 assert (nb_operands
== 2);
1550 assert (operands
[0].reg1
!= REG_NONE
);
1552 code
= opcode
->opcode
& 0x0FF;
1554 f
= m68hc11_new_insn (1);
1555 number_to_chars_bigendian (f
, code
, 1);
1557 n
= operands
[1].exp
.X_add_number
;
1558 code
= operands
[0].reg1
;
1560 if (operands
[0].reg1
== REG_NONE
|| operands
[0].reg1
== REG_CCR
1561 || operands
[0].reg1
== REG_PC
)
1562 as_bad (_("Invalid register for dbcc/tbcc instruction."));
1564 if (opcode
->format
& M6812_OP_IBCC_MARKER
)
1566 else if (opcode
->format
& M6812_OP_TBCC_MARKER
)
1569 if (!(opcode
->format
& M6812_OP_EQ_MARKER
))
1572 /* Turn into a long branch:
1573 - when force long branch option (and not for jbcc pseudos),
1574 - when jdbcc and the constant is out of -256..255 range,
1575 - when branch optimization is allowed and branch out of range. */
1576 if ((jmp_mode
== 0 && flag_force_long_jumps
)
1577 || (operands
[1].exp
.X_op
== O_constant
1578 && (!check_range (n
, M6812_OP_IBCC_MARKER
) &&
1579 (jmp_mode
== 1 || flag_fixed_branchs
== 0))))
1583 number_to_chars_bigendian (f
, code
, 1);
1584 number_to_chars_bigendian (f
+ 1, M6812_JMP
, 1);
1585 fixup16 (&operands
[0].exp
, M6811_OP_IND16
, M6811_OP_IND16
);
1589 /* Branch with a constant that must fit in 9-bits. */
1590 if (operands
[1].exp
.X_op
== O_constant
)
1592 if (!check_range (n
, M6812_OP_IBCC_MARKER
))
1594 as_bad (_("Operand out of range for a relative branch: `%ld'"),
1603 number_to_chars_bigendian (f
, code
, 1);
1604 number_to_chars_bigendian (f
+ 1, n
& 0x0FF, 1);
1609 /* Branch offset must fit in 8-bits, don't do some relax. */
1610 if (jmp_mode
== 0 && flag_fixed_branchs
)
1612 fixup8 (&operands
[0].exp
, M6811_OP_JUMP_REL
, M6811_OP_JUMP_REL
);
1618 number_to_chars_bigendian (f
, code
, 1);
1619 number_to_chars_bigendian (f
+ 1, 0, 1);
1620 frag_var (rs_machine_dependent
, 3, 3,
1621 ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_UNDF
),
1622 operands
[1].exp
.X_add_symbol
, (offsetT
) n
, f
);
1627 #define OP_EXTENDED (M6811_OP_PAGE2 | M6811_OP_PAGE3 | M6811_OP_PAGE4)
1629 /* Assemble the post index byte for 68HC12 extended addressing modes. */
1631 build_indexed_byte (op
, format
, move_insn
)
1633 int format ATTRIBUTE_UNUSED
;
1636 unsigned char byte
= 0;
1641 val
= op
->exp
.X_add_number
;
1643 if (mode
& M6812_AUTO_INC_DEC
)
1646 if (mode
& (M6812_POST_INC
| M6812_POST_DEC
))
1649 if (op
->exp
.X_op
== O_constant
)
1651 if (!check_range (val
, mode
))
1653 as_bad (_("Increment/decrement value is out of range: `%ld'."),
1656 if (mode
& (M6812_POST_INC
| M6812_PRE_INC
))
1657 byte
|= (val
- 1) & 0x07;
1659 byte
|= (8 - ((val
) & 7)) | 0x8;
1664 as_fatal (_("Expecting a register."));
1679 as_bad (_("Invalid register for post/pre increment."));
1684 number_to_chars_bigendian (f
, byte
, 1);
1688 if (mode
& M6812_OP_IDX
)
1709 as_bad (_("Invalid register."));
1712 if (op
->exp
.X_op
== O_constant
)
1714 if (!check_range (val
, M6812_OP_IDX
))
1716 as_bad (_("Offset out of 16-bit range: %ld."), val
);
1719 if (move_insn
&& !(val
>= -16 && val
<= 15))
1721 as_bad (_("Offset out of 5-bit range for movw/movb insn: %ld."),
1726 if (val
>= -16 && val
<= 15 && !(mode
& M6812_OP_IDX_2
))
1731 number_to_chars_bigendian (f
, byte
, 1);
1734 else if (val
>= -256 && val
<= 255 && !(mode
& M6812_OP_IDX_2
))
1741 number_to_chars_bigendian (f
, byte
, 1);
1742 number_to_chars_bigendian (f
+ 1, val
& 0x0FF, 1);
1748 if (mode
& M6812_OP_IDX_2
)
1754 number_to_chars_bigendian (f
, byte
, 1);
1755 number_to_chars_bigendian (f
+ 1, val
& 0x0FFFF, 2);
1759 if (op
->reg1
!= REG_PC
)
1761 byte
= (byte
<< 3) | 0xe2;
1763 number_to_chars_bigendian (f
, byte
, 1);
1766 fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 2,
1767 &op
->exp
, false, BFD_RELOC_16
);
1768 number_to_chars_bigendian (f
, 0, 2);
1773 number_to_chars_bigendian (f
, byte
, 1);
1774 frag_var (rs_machine_dependent
, 2, 2,
1775 ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_UNDF
),
1776 op
->exp
.X_add_symbol
,
1777 op
->exp
.X_add_number
, f
);
1782 if (mode
& M6812_OP_REG
)
1784 if (mode
& M6812_OP_IDX_2
)
1786 if (op
->reg1
!= REG_D
)
1787 as_bad (_("Expecting register D for indexed indirect mode."));
1789 as_bad (_("Indexed indirect mode is not allowed for movb/movw."));
1806 as_bad (_("Invalid accumulator register."));
1831 as_bad (_("Invalid indexed register."));
1835 number_to_chars_bigendian (f
, byte
, 1);
1839 as_fatal (_("Addressing mode not implemented yet."));
1843 /* Assemble the 68HC12 register mode byte. */
1845 build_reg_mode (op
, format
)
1852 if (format
& M6812_OP_SEX_MARKER
1853 && op
->reg1
!= REG_A
&& op
->reg1
!= REG_B
&& op
->reg1
!= REG_CCR
)
1854 as_bad (_("Invalid source register for this instruction, use 'tfr'."));
1855 else if (op
->reg1
== REG_NONE
|| op
->reg1
== REG_PC
)
1856 as_bad (_("Invalid source register."));
1858 if (format
& M6812_OP_SEX_MARKER
1859 && op
->reg2
!= REG_D
1860 && op
->reg2
!= REG_X
&& op
->reg2
!= REG_Y
&& op
->reg2
!= REG_SP
)
1861 as_bad (_("Invalid destination register for this instruction, use 'tfr'."));
1862 else if (op
->reg2
== REG_NONE
|| op
->reg2
== REG_PC
)
1863 as_bad (_("Invalid destination register."));
1865 byte
= (op
->reg1
<< 4) | (op
->reg2
);
1866 if (format
& M6812_OP_EXG_MARKER
)
1870 number_to_chars_bigendian (f
, byte
, 1);
1874 /* build_insn takes a pointer to the opcode entry in the opcode table,
1875 the array of operand expressions and builds the correspding instruction.
1876 This operation only deals with non relative jumps insn (need special
1879 build_insn (opcode
, operands
, nb_operands
)
1880 struct m68hc11_opcode
*opcode
;
1882 int nb_operands ATTRIBUTE_UNUSED
;
1889 /* Put the page code instruction if there is one. */
1890 format
= opcode
->format
;
1891 if (format
& OP_EXTENDED
)
1895 f
= m68hc11_new_insn (2);
1896 if (format
& M6811_OP_PAGE2
)
1897 page_code
= M6811_OPCODE_PAGE2
;
1898 else if (format
& M6811_OP_PAGE3
)
1899 page_code
= M6811_OPCODE_PAGE3
;
1901 page_code
= M6811_OPCODE_PAGE4
;
1903 number_to_chars_bigendian (f
, page_code
, 1);
1907 f
= m68hc11_new_insn (1);
1909 number_to_chars_bigendian (f
, opcode
->opcode
, 1);
1913 /* The 68HC12 movb and movw instructions are special. We have to handle
1914 them in a special way. */
1915 if (format
& (M6812_OP_IND16_P2
| M6812_OP_IDX_P2
))
1918 if (format
& M6812_OP_IDX
)
1920 build_indexed_byte (&operands
[0], format
, 1);
1922 format
&= ~M6812_OP_IDX
;
1924 if (format
& M6812_OP_IDX_P2
)
1926 build_indexed_byte (&operands
[1], format
, 1);
1928 format
&= ~M6812_OP_IDX_P2
;
1932 if (format
& (M6811_OP_DIRECT
| M6811_OP_IMM8
))
1934 fixup8 (&operands
[i
].exp
,
1935 format
& (M6811_OP_DIRECT
| M6811_OP_IMM8
| M6812_OP_TRAP_ID
),
1939 else if (format
& (M6811_OP_IMM16
| M6811_OP_IND16
))
1941 fixup16 (&operands
[i
].exp
, format
& (M6811_OP_IMM16
| M6811_OP_IND16
),
1945 else if (format
& (M6811_OP_IX
| M6811_OP_IY
))
1947 if ((format
& M6811_OP_IX
) && (operands
[0].reg1
!= REG_X
))
1948 as_bad (_("Invalid indexed register, expecting register X."));
1949 if ((format
& M6811_OP_IY
) && (operands
[0].reg1
!= REG_Y
))
1950 as_bad (_("Invalid indexed register, expecting register Y."));
1952 fixup8 (&operands
[0].exp
, M6811_OP_IX
, operands
[0].mode
);
1956 (M6812_OP_IDX
| M6812_OP_IDX_2
| M6812_OP_IDX_1
| M6812_OP_D_IDX
))
1958 build_indexed_byte (&operands
[i
], format
, move_insn
);
1961 else if (format
& M6812_OP_REG
&& current_architecture
& cpu6812
)
1963 build_reg_mode (&operands
[i
], format
);
1966 if (format
& M6811_OP_BITMASK
)
1968 fixup8 (&operands
[i
].exp
, M6811_OP_BITMASK
, operands
[i
].mode
);
1971 if (format
& M6811_OP_JUMP_REL
)
1973 fixup8 (&operands
[i
].exp
, M6811_OP_JUMP_REL
, operands
[i
].mode
);
1975 else if (format
& M6812_OP_IND16_P2
)
1977 fixup16 (&operands
[1].exp
, M6811_OP_IND16
, operands
[1].mode
);
1981 /* Opcode identification and operand analysis. */
1983 /* find() gets a pointer to an entry in the opcode table. It must look at all
1984 opcodes with the same name and use the operands to choose the correct
1985 opcode. Returns the opcode pointer if there was a match and 0 if none. */
1986 static struct m68hc11_opcode
*
1987 find (opc
, operands
, nb_operands
)
1988 struct m68hc11_opcode_def
*opc
;
1993 struct m68hc11_opcode
*opcode
;
1994 struct m68hc11_opcode
*op_indirect
;
1997 opcode
= opc
->opcode
;
1999 /* Now search the opcode table table for one with operands
2000 that matches what we've got. We're only done if the operands matched so
2001 far AND there are no more to check. */
2002 for (pos
= match
= 0; match
== 0 && pos
< opc
->nb_modes
; pos
++, opcode
++)
2004 int poss_indirect
= 0;
2005 long format
= opcode
->format
;
2009 if (opcode
->format
& M6811_OP_MASK
)
2011 if (opcode
->format
& M6811_OP_BITMASK
)
2013 if (opcode
->format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
2015 if (opcode
->format
& (M6812_OP_IND16_P2
| M6812_OP_IDX_P2
))
2018 for (i
= 0; expect
== nb_operands
&& i
< nb_operands
; i
++)
2020 int mode
= operands
[i
].mode
;
2022 if (mode
& M6811_OP_IMM16
)
2025 (M6811_OP_IMM8
| M6811_OP_IMM16
| M6811_OP_BITMASK
))
2029 if (mode
== M6811_OP_DIRECT
)
2031 if (format
& M6811_OP_DIRECT
)
2034 /* If the operand is a page 0 operand, remember a
2035 possible <abs-16> addressing mode. We mark
2036 this and continue to check other operands. */
2037 if (format
& M6811_OP_IND16
2038 && flag_strict_direct_addressing
&& op_indirect
== 0)
2045 if (mode
& M6811_OP_IND16
)
2047 if (i
== 0 && (format
& M6811_OP_IND16
) != 0)
2049 if (i
!= 0 && (format
& M6812_OP_IND16_P2
) != 0)
2051 if (i
== 0 && (format
& M6811_OP_BITMASK
))
2054 if (mode
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
2056 if (format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
2059 if (mode
& M6812_OP_REG
)
2062 && (format
& M6812_OP_REG
)
2063 && (operands
[i
].reg2
== REG_NONE
))
2066 && (format
& M6812_OP_REG
)
2067 && (format
& M6812_OP_REG_2
)
2068 && (operands
[i
].reg2
!= REG_NONE
))
2071 && (format
& M6812_OP_IDX
)
2072 && (operands
[i
].reg2
!= REG_NONE
))
2075 && (format
& M6812_OP_D_IDX
))
2078 && (format
& M6812_OP_IDX
)
2079 && (format
& (M6812_OP_IND16_P2
| M6812_OP_IDX_P2
)))
2082 && (format
& M6812_OP_IDX_P2
))
2086 if (mode
& M6812_OP_IDX
)
2088 if (format
& M6811_OP_IX
&& operands
[i
].reg1
== REG_X
)
2090 if (format
& M6811_OP_IY
&& operands
[i
].reg1
== REG_Y
)
2093 && format
& (M6812_OP_IDX
| M6812_OP_IDX_1
| M6812_OP_IDX_2
)
2094 && (operands
[i
].reg1
== REG_X
2095 || operands
[i
].reg1
== REG_Y
2096 || operands
[i
].reg1
== REG_SP
2097 || operands
[i
].reg1
== REG_PC
))
2099 if (i
== 1 && format
& M6812_OP_IDX_P2
)
2102 if (mode
& M6812_AUTO_INC_DEC
)
2105 && format
& (M6812_OP_IDX
| M6812_OP_IDX_1
|
2108 if (i
== 1 && format
& M6812_OP_IDX_P2
)
2113 match
= i
== nb_operands
;
2115 /* Operands are ok but an operand uses page 0 addressing mode
2116 while the insn supports abs-16 mode. Keep a reference to this
2117 insns in case there is no insn supporting page 0 addressing. */
2118 if (match
&& poss_indirect
)
2120 op_indirect
= opcode
;
2127 /* Page 0 addressing is used but not supported by any insn.
2128 If absolute addresses are supported, we use that insn. */
2129 if (match
== 0 && op_indirect
)
2131 opcode
= op_indirect
;
2143 /* Find the real opcode and its associated operands. We use a progressive
2144 approach here. On entry, 'opc' points to the first opcode in the
2145 table that matches the opcode name in the source line. We try to
2146 isolate an operand, find a possible match in the opcode table.
2147 We isolate another operand if no match were found. The table 'operands'
2148 is filled while operands are recognized.
2150 Returns the opcode pointer that matches the opcode name in the
2151 source line and the associated operands. */
2152 static struct m68hc11_opcode
*
2153 find_opcode (opc
, operands
, nb_operands
)
2154 struct m68hc11_opcode_def
*opc
;
2158 struct m68hc11_opcode
*opcode
;
2161 if (opc
->max_operands
== 0)
2167 for (i
= 0; i
< opc
->max_operands
;)
2171 result
= get_operand (&operands
[i
], i
, opc
->format
);
2175 /* Special case where the bitmask of the bclr/brclr
2176 instructions is not introduced by #.
2177 Example: bclr 3,x $80. */
2178 if (i
== 1 && (opc
->format
& M6811_OP_BITMASK
)
2179 && (operands
[i
].mode
& M6811_OP_IND16
))
2181 operands
[i
].mode
= M6811_OP_IMM16
;
2186 if (i
>= opc
->min_operands
)
2188 opcode
= find (opc
, operands
, i
);
2193 if (*input_line_pointer
== ',')
2194 input_line_pointer
++;
2200 #define M6812_XBCC_MARKER (M6812_OP_TBCC_MARKER \
2201 | M6812_OP_DBCC_MARKER \
2202 | M6812_OP_IBCC_MARKER)
2204 /* Gas line assembler entry point. */
2206 /* This is the main entry point for the machine-dependent assembler. str
2207 points to a machine-dependent instruction. This function is supposed to
2208 emit the frags/bytes it assembles to. */
2213 struct m68hc11_opcode_def
*opc
;
2214 struct m68hc11_opcode
*opcode
;
2216 unsigned char *op_start
, *save
;
2217 unsigned char *op_end
;
2220 operand operands
[M6811_MAX_OPERANDS
];
2222 int branch_optimize
= 0;
2225 /* Drop leading whitespace. */
2229 /* Find the opcode end and get the opcode in 'name'. The opcode is forced
2230 lower case (the opcode table only has lower case op-codes). */
2231 for (op_start
= op_end
= (unsigned char *) (str
);
2232 *op_end
&& nlen
< 20 && !is_end_of_line
[*op_end
] && *op_end
!= ' ';
2235 name
[nlen
] = tolower (op_start
[nlen
]);
2242 as_bad (_("No instruction or missing opcode."));
2246 /* Find the opcode definition given its name. */
2247 opc
= (struct m68hc11_opcode_def
*) hash_find (m68hc11_hash
, name
);
2249 /* If it's not recognized, look for 'jbsr' and 'jbxx'. These are
2250 pseudo insns for relative branch. For these branchs, we always
2251 optimize them (turned into absolute branchs) even if --short-branchs
2253 if (opc
== NULL
&& name
[0] == 'j' && name
[1] == 'b')
2255 opc
= (struct m68hc11_opcode_def
*) hash_find (m68hc11_hash
, &name
[1]);
2257 && (!(opc
->format
& M6811_OP_JUMP_REL
)
2258 || (opc
->format
& M6811_OP_BITMASK
)))
2261 branch_optimize
= 1;
2264 /* The following test should probably be removed. This is not conform
2265 to Motorola assembler specs. */
2266 if (opc
== NULL
&& flag_mri
)
2268 if (*op_end
== ' ' || *op_end
== '\t')
2270 while (*op_end
== ' ' || *op_end
== '\t')
2275 (is_end_of_line
[op_end
[1]]
2276 || op_end
[1] == ' ' || op_end
[1] == '\t'
2277 || !isalnum (op_end
[1])))
2278 && (*op_end
== 'a' || *op_end
== 'b'
2279 || *op_end
== 'A' || *op_end
== 'B'
2280 || *op_end
== 'd' || *op_end
== 'D'
2281 || *op_end
== 'x' || *op_end
== 'X'
2282 || *op_end
== 'y' || *op_end
== 'Y'))
2284 name
[nlen
++] = tolower (*op_end
++);
2286 opc
= (struct m68hc11_opcode_def
*) hash_find (m68hc11_hash
,
2292 /* Identify a possible instruction alias. There are some on the
2293 68HC12 to emulate a few 68HC11 instructions. */
2294 if (opc
== NULL
&& (current_architecture
& cpu6812
))
2298 for (i
= 0; i
< m68hc12_num_alias
; i
++)
2299 if (strcmp (m68hc12_alias
[i
].name
, name
) == 0)
2305 if (opc
== NULL
&& alias_id
< 0)
2307 as_bad (_("Opcode `%s' is not recognized."), name
);
2310 save
= input_line_pointer
;
2311 input_line_pointer
= op_end
;
2316 opcode
= find_opcode (opc
, operands
, &nb_operands
);
2321 if ((opcode
|| alias_id
>= 0) && !flag_mri
)
2323 char *p
= input_line_pointer
;
2325 while (*p
== ' ' || *p
== '\t' || *p
== '\n' || *p
== '\r')
2328 if (*p
!= '\n' && *p
)
2329 as_bad (_("Garbage at end of instruction: `%s'."), p
);
2332 input_line_pointer
= save
;
2336 char *f
= m68hc11_new_insn (m68hc12_alias
[alias_id
].size
);
2338 number_to_chars_bigendian (f
, m68hc12_alias
[alias_id
].code1
, 1);
2339 if (m68hc12_alias
[alias_id
].size
> 1)
2340 number_to_chars_bigendian (f
+ 1, m68hc12_alias
[alias_id
].code2
, 1);
2345 /* Opcode is known but does not have valid operands. Print out the
2346 syntax for this opcode. */
2349 if (flag_print_insn_syntax
)
2350 print_insn_format (name
);
2352 as_bad (_("Invalid operand for `%s'"), name
);
2356 /* Treat dbeq/ibeq/tbeq instructions in a special way. The branch is
2357 relative and must be in the range -256..255 (9-bits). */
2358 if ((opcode
->format
& M6812_XBCC_MARKER
)
2359 && (opcode
->format
& M6811_OP_JUMP_REL
))
2360 build_dbranch_insn (opcode
, operands
, nb_operands
);
2362 /* Relative jumps instructions are taken care of separately. We have to make
2363 sure that the relative branch is within the range -128..127. If it's out
2364 of range, the instructions are changed into absolute instructions.
2365 This is not supported for the brset and brclr instructions. */
2366 else if ((opcode
->format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
2367 && !(opcode
->format
& M6811_OP_BITMASK
))
2368 build_jump_insn (opcode
, operands
, nb_operands
, branch_optimize
);
2370 build_insn (opcode
, operands
, nb_operands
);
2373 /* Relocation, relaxation and frag conversions. */
2375 md_pcrel_from_section (fixp
, sec
)
2380 if (fixp
->fx_addsy
!= (symbolS
*) NULL
2381 && (!S_IS_DEFINED (fixp
->fx_addsy
)
2382 || (S_GET_SEGMENT (fixp
->fx_addsy
) != sec
)))
2385 adjust
= fixp
->fx_pcrel_adjust
;
2386 return fixp
->fx_frag
->fr_address
+ fixp
->fx_where
+ adjust
;
2389 /* If while processing a fixup, a reloc really needs to be created
2390 then it is done here. */
2392 tc_gen_reloc (section
, fixp
)
2398 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
2399 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
2400 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
2401 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
2402 if (fixp
->fx_r_type
== 0)
2403 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_16
);
2405 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
2406 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
2408 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2409 _("Relocation %d is not supported by object file format."),
2410 (int) fixp
->fx_r_type
);
2414 if (!fixp
->fx_pcrel
)
2415 reloc
->addend
= fixp
->fx_addnumber
;
2417 reloc
->addend
= (section
->vma
2418 + (fixp
->fx_pcrel_adjust
== 64
2419 ? -1 : fixp
->fx_pcrel_adjust
)
2420 + fixp
->fx_addnumber
2421 + md_pcrel_from_section (fixp
, section
));
2426 md_convert_frag (abfd
, sec
, fragP
)
2427 bfd
*abfd ATTRIBUTE_UNUSED
;
2428 asection
*sec ATTRIBUTE_UNUSED
;
2434 char *buffer_address
= fragP
->fr_literal
;
2436 /* Address in object code of the displacement. */
2437 register int object_address
= fragP
->fr_fix
+ fragP
->fr_address
;
2439 buffer_address
+= fragP
->fr_fix
;
2441 /* The displacement of the address, from current location. */
2442 value
= fragP
->fr_symbol
? S_GET_VALUE (fragP
->fr_symbol
) : 0;
2443 disp
= (value
+ fragP
->fr_offset
) - object_address
;
2444 disp
+= symbol_get_frag (fragP
->fr_symbol
)->fr_address
;
2446 switch (fragP
->fr_subtype
)
2448 case ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_BYTE
):
2449 fragP
->fr_opcode
[1] = disp
;
2452 case ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_WORD
):
2453 /* This relax is only for bsr and bra. */
2454 assert (IS_OPCODE (fragP
->fr_opcode
[0], M6811_BSR
)
2455 || IS_OPCODE (fragP
->fr_opcode
[0], M6811_BRA
)
2456 || IS_OPCODE (fragP
->fr_opcode
[0], M6812_BSR
));
2458 fragP
->fr_opcode
[0] = convert_branch (fragP
->fr_opcode
[0]);
2460 fix_new (fragP
, fragP
->fr_fix
- 1, 2,
2461 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_16
);
2465 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
, STATE_BYTE
):
2466 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
, STATE_BYTE
):
2467 fragP
->fr_opcode
[1] = disp
;
2470 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
, STATE_WORD
):
2471 /* Invert branch. */
2472 fragP
->fr_opcode
[0] ^= 1;
2473 fragP
->fr_opcode
[1] = 3; /* Branch offset. */
2474 buffer_address
[0] = M6811_JMP
;
2475 fix_new (fragP
, fragP
->fr_fix
+ 1, 2,
2476 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_16
);
2480 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
, STATE_WORD
):
2481 /* Translate branch into a long branch. */
2482 fragP
->fr_opcode
[1] = fragP
->fr_opcode
[0];
2483 fragP
->fr_opcode
[0] = M6811_OPCODE_PAGE2
;
2485 fixp
= fix_new (fragP
, fragP
->fr_fix
, 2,
2486 fragP
->fr_symbol
, fragP
->fr_offset
, 1,
2487 BFD_RELOC_16_PCREL
);
2488 fixp
->fx_pcrel_adjust
= 2;
2492 case ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS5
):
2493 fragP
->fr_opcode
[0] = fragP
->fr_opcode
[0] << 6;
2494 if ((fragP
->fr_opcode
[0] & 0x0ff) == 0x0c0)
2495 fragP
->fr_opcode
[0] |= disp
& 0x1f;
2497 fragP
->fr_opcode
[0] |= value
& 0x1f;
2500 case ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS9
):
2501 fragP
->fr_opcode
[0] = (fragP
->fr_opcode
[0] << 3);
2502 fragP
->fr_opcode
[0] |= 0xE0;
2503 fix_new (fragP
, fragP
->fr_fix
, 1,
2504 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_8
);
2508 case ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS16
):
2509 fragP
->fr_opcode
[0] = (fragP
->fr_opcode
[0] << 3);
2510 fragP
->fr_opcode
[0] |= 0xe2;
2511 if ((fragP
->fr_opcode
[0] & 0x0ff) == 0x0fa)
2513 fixp
= fix_new (fragP
, fragP
->fr_fix
, 2,
2514 fragP
->fr_symbol
, fragP
->fr_offset
,
2515 1, BFD_RELOC_16_PCREL
);
2516 fixp
->fx_pcrel_adjust
= 2;
2520 fix_new (fragP
, fragP
->fr_fix
, 2,
2521 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_16
);
2526 case ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_BYTE
):
2528 fragP
->fr_opcode
[0] |= 0x10;
2530 fragP
->fr_opcode
[1] = disp
& 0x0FF;
2533 case ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_WORD
):
2534 /* Invert branch. */
2535 fragP
->fr_opcode
[0] ^= 0x20;
2536 fragP
->fr_opcode
[1] = 3; /* Branch offset. */
2537 buffer_address
[0] = M6812_JMP
;
2538 fix_new (fragP
, fragP
->fr_fix
+ 1, 2,
2539 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_16
);
2548 /* On an ELF system, we can't relax a weak symbol. The weak symbol
2549 can be overridden at final link time by a non weak symbol. We can
2550 relax externally visible symbol because there is no shared library
2551 and such symbol can't be overridden (unless they are weak). */
2553 relaxable_symbol (symbol
)
2556 return ! S_IS_WEAK (symbol
);
2559 /* Force truly undefined symbols to their maximum size, and generally set up
2560 the frag list to be relaxed. */
2562 md_estimate_size_before_relax (fragP
, segment
)
2567 char *buffer_address
= fragP
->fr_fix
+ fragP
->fr_literal
;
2569 old_fr_fix
= fragP
->fr_fix
;
2571 switch (fragP
->fr_subtype
)
2573 case ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_UNDF
):
2575 /* This relax is only for bsr and bra. */
2576 assert (IS_OPCODE (fragP
->fr_opcode
[0], M6811_BSR
)
2577 || IS_OPCODE (fragP
->fr_opcode
[0], M6811_BRA
)
2578 || IS_OPCODE (fragP
->fr_opcode
[0], M6812_BSR
));
2580 /* A relaxable case. */
2581 if (S_GET_SEGMENT (fragP
->fr_symbol
) == segment
2582 && relaxable_symbol (fragP
->fr_symbol
))
2584 fragP
->fr_subtype
= ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_BYTE
);
2588 if (flag_fixed_branchs
)
2589 as_bad_where (fragP
->fr_file
, fragP
->fr_line
,
2590 _("bra or bsr with undefined symbol."));
2592 /* The symbol is undefined or in a separate section. Turn bra into a
2593 jmp and bsr into a jsr. The insn becomes 3 bytes long (instead of
2594 2). A fixup is necessary for the unresolved symbol address. */
2596 fragP
->fr_opcode
[0] = convert_branch (fragP
->fr_opcode
[0]);
2599 fix_new (fragP
, old_fr_fix
- 1, 2, fragP
->fr_symbol
,
2600 fragP
->fr_offset
, 0, BFD_RELOC_16
);
2605 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
, STATE_UNDF
):
2606 assert (current_architecture
& cpu6811
);
2608 if (S_GET_SEGMENT (fragP
->fr_symbol
) == segment
2609 && relaxable_symbol (fragP
->fr_symbol
))
2611 fragP
->fr_subtype
= ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
,
2616 fragP
->fr_opcode
[0] ^= 1; /* Reverse sense of branch. */
2617 fragP
->fr_opcode
[1] = 3; /* Skip next jmp insn (3 bytes). */
2619 /* Don't use fr_opcode[2] because this may be
2620 in a different frag. */
2621 buffer_address
[0] = M6811_JMP
;
2624 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
2625 fragP
->fr_offset
, 0, BFD_RELOC_16
);
2631 case ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_UNDF
):
2632 assert (current_architecture
& cpu6812
);
2634 if (S_GET_SEGMENT (fragP
->fr_symbol
) == segment
2635 && relaxable_symbol (fragP
->fr_symbol
))
2637 fragP
->fr_subtype
= ENCODE_RELAX (STATE_INDEXED_OFFSET
,
2642 /* Switch the indexed operation to 16-bit mode. */
2643 fragP
->fr_opcode
[0] = fragP
->fr_opcode
[0] << 3;
2644 fragP
->fr_opcode
[0] |= 0xe2;
2646 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
2647 fragP
->fr_offset
, 0, BFD_RELOC_16
);
2653 case ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_UNDF
):
2654 assert (current_architecture
& cpu6812
);
2656 if (S_GET_SEGMENT (fragP
->fr_symbol
) == segment
2657 && relaxable_symbol (fragP
->fr_symbol
))
2659 fragP
->fr_subtype
= ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_BYTE
);
2663 fragP
->fr_opcode
[0] ^= 0x20; /* Reverse sense of branch. */
2664 fragP
->fr_opcode
[1] = 3; /* Skip next jmp insn (3 bytes). */
2666 /* Don't use fr_opcode[2] because this may be
2667 in a different frag. */
2668 buffer_address
[0] = M6812_JMP
;
2671 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
2672 fragP
->fr_offset
, 0, BFD_RELOC_16
);
2678 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
, STATE_UNDF
):
2679 assert (current_architecture
& cpu6812
);
2681 if (S_GET_SEGMENT (fragP
->fr_symbol
) == segment
2682 && relaxable_symbol (fragP
->fr_symbol
))
2684 fragP
->fr_subtype
= ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
,
2689 /* Translate into a lbcc branch. */
2690 fragP
->fr_opcode
[1] = fragP
->fr_opcode
[0];
2691 fragP
->fr_opcode
[0] = M6811_OPCODE_PAGE2
;
2693 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
2694 fragP
->fr_offset
, 0, BFD_RELOC_16_PCREL
);
2701 as_fatal (_("Subtype %d is not recognized."), fragP
->fr_subtype
);
2704 return (fragP
->fr_fix
- old_fr_fix
);
2708 md_apply_fix (fixp
, valuep
)
2716 if (fixp
->fx_addsy
== (symbolS
*) NULL
)
2721 else if (fixp
->fx_pcrel
)
2727 value
= fixp
->fx_offset
;
2728 if (fixp
->fx_subsy
!= (symbolS
*) NULL
)
2730 if (S_GET_SEGMENT (fixp
->fx_subsy
) == absolute_section
)
2732 value
-= S_GET_VALUE (fixp
->fx_subsy
);
2736 /* We don't actually support subtracting a symbol. */
2737 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2738 _("Expression too complex."));
2743 op_type
= fixp
->fx_r_type
;
2745 /* Patch the instruction with the resolved operand. Elf relocation
2746 info will also be generated to take care of linker/loader fixups.
2747 The 68HC11 addresses only 64Kb, we are only concerned by 8 and 16-bit
2748 relocs. BFD_RELOC_8 is basically used for .page0 access (the linker
2749 will warn for overflows). BFD_RELOC_8_PCREL should not be generated
2750 because it's either resolved or turned out into non-relative insns (see
2751 relax table, bcc, bra, bsr transformations)
2753 The BFD_RELOC_32 is necessary for the support of --gstabs. */
2754 where
= fixp
->fx_frag
->fr_literal
+ fixp
->fx_where
;
2756 switch (fixp
->fx_r_type
)
2759 bfd_putb32 ((bfd_vma
) value
, (unsigned char *) where
);
2763 case BFD_RELOC_16_PCREL
:
2764 bfd_putb16 ((bfd_vma
) value
, (unsigned char *) where
);
2765 if (value
< -65537 || value
> 65535)
2766 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2767 _("Value out of 16-bit range."));
2770 case BFD_RELOC_M68HC11_HI8
:
2774 case BFD_RELOC_M68HC11_LO8
:
2777 bfd_putb8 ((bfd_vma
) value
, (unsigned char *) where
);
2779 ((bfd_byte
*) where
)[0] = (bfd_byte
) value
;
2782 case BFD_RELOC_8_PCREL
:
2784 bfd_putb8 ((bfd_vma
) value
, (unsigned char *) where
);
2786 ((bfd_byte
*) where
)[0] = (bfd_byte
) value
;
2788 if (value
< -128 || value
> 127)
2789 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2790 _("Value %ld too large for 8-bit PC-relative branch."),
2794 case BFD_RELOC_M68HC11_3B
:
2795 if (value
<= 0 || value
> 8)
2796 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2797 _("Auto increment/decrement offset '%ld' is out of range."),
2804 where
[0] = where
[0] | (value
& 0x07);
2808 as_fatal (_("Line %d: unknown relocation type: 0x%x."),
2809 fixp
->fx_line
, fixp
->fx_r_type
);