1 /* tc-m68hc11.c -- Assembler code for the Motorola 68HC11 & 68HC12.
2 Copyright (C) 1999, 2000 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
[] =
66 {1, 1, 0, 0}, /* First entries aren't used. */
67 {1, 1, 0, 0}, /* For no good reason except. */
68 {1, 1, 0, 0}, /* that the VAX doesn't either. */
72 These insns are translated into b!cc +3 jmp L. */
73 {(127), (-128), 0, ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
, STATE_WORD
)},
78 /* Relax for bsr <L> and bra <L>.
79 These insns are translated into jsr and jmp. */
80 {(127), (-128), 0, ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_WORD
)},
85 /* Relax for indexed offset: 5-bits, 9-bits, 16-bits. */
86 {(15), (-16), 0, ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS9
)},
87 {(255), (-256), 1, ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS16
)},
91 /* Relax for dbeq/ibeq/tbeq r,<L>:
92 These insns are translated into db!cc +3 jmp L. */
93 {(255), (-256), 0, ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_WORD
)},
98 /* Relax for bcc <L> on 68HC12.
99 These insns are translated into lbcc <L>. */
100 {(127), (-128), 0, ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
, STATE_WORD
)},
107 /* 68HC11 and 68HC12 registers. They are numbered according to the 68HC12. */
108 typedef enum register_id
121 typedef struct operand
129 struct m68hc11_opcode_def
136 struct m68hc11_opcode
*opcode
;
139 static struct m68hc11_opcode_def
*m68hc11_opcode_defs
= 0;
140 static int m68hc11_nb_opcode_defs
= 0;
149 static alias alias_opcodes
[] =
157 /* Local functions. */
158 static register_id reg_name_search
PARAMS ((char *));
159 static register_id register_name
PARAMS ((void));
160 static int check_range
PARAMS ((long, int));
161 static void print_opcode_list
PARAMS ((void));
162 static void get_default_target
PARAMS ((void));
163 static void print_insn_format
PARAMS ((char *));
164 static int get_operand
PARAMS ((operand
*, int, long));
165 static void fixup8
PARAMS ((expressionS
*, int, int));
166 static void fixup16
PARAMS ((expressionS
*, int, int));
167 static struct m68hc11_opcode
*find_opcode
168 PARAMS ((struct m68hc11_opcode_def
*, operand
*, int *));
169 static void build_jump_insn
170 PARAMS ((struct m68hc11_opcode
*, operand
*, int, int));
171 static void build_insn
172 PARAMS ((struct m68hc11_opcode
*, operand
*, int));
174 /* Controls whether relative branches can be turned into long branches.
175 When the relative offset is too large, the insn are changed:
183 Setting the flag forbidds this. */
184 static short flag_fixed_branchs
= 0;
186 /* Force to use long jumps (absolute) instead of relative branches. */
187 static short flag_force_long_jumps
= 0;
189 /* Change the direct addressing mode into an absolute addressing mode
190 when the insn does not support direct addressing.
191 For example, "clr *ZD0" is normally not possible and is changed
193 static short flag_strict_direct_addressing
= 1;
195 /* When an opcode has invalid operand, print out the syntax of the opcode
197 static short flag_print_insn_syntax
= 0;
199 /* Dumps the list of instructions with syntax and then exit:
200 1 -> Only dumps the list (sorted by name)
201 2 -> Generate an example (or test) that can be compiled. */
202 static short flag_print_opcodes
= 0;
204 /* Opcode hash table. */
205 static struct hash_control
*m68hc11_hash
;
207 /* Current cpu (either cpu6811 or cpu6812). This is determined automagically
208 by 'get_default_target' by looking at default BFD vector. This is overriden
209 with the -m<cpu> option. */
210 static int current_architecture
= 0;
212 /* Default cpu determined by 'get_default_target'. */
213 static const char *default_cpu
;
215 /* Number of opcodes in the sorted table (filtered by current cpu). */
216 static int num_opcodes
;
218 /* The opcodes sorted by name and filtered by current cpu. */
219 static struct m68hc11_opcode
*m68hc11_sorted_opcodes
;
221 /* These are the machine dependent pseudo-ops. These are included so
222 the assembler can work on the output from the SUN C compiler, which
225 /* This table describes all the machine specific pseudo-ops the assembler
226 has to support. The fields are:
227 pseudo-op name without dot
228 function to call to execute this pseudo-op
229 Integer arg to pass to the function. */
230 const pseudo_typeS md_pseudo_table
[] =
232 /* The following pseudo-ops are supported for MRI compatibility. */
235 {"fcc", stringer
, 1},
237 {"file", dwarf2_directive_file
, 0},
238 {"loc", dwarf2_directive_loc
, 0},
243 /* Options and initialization. */
245 CONST
char *md_shortopts
= "Sm:";
247 struct option md_longopts
[] =
249 #define OPTION_FORCE_LONG_BRANCH (OPTION_MD_BASE)
250 {"force-long-branchs", no_argument
, NULL
, OPTION_FORCE_LONG_BRANCH
},
252 #define OPTION_SHORT_BRANCHS (OPTION_MD_BASE + 1)
253 {"short-branchs", no_argument
, NULL
, OPTION_SHORT_BRANCHS
},
255 #define OPTION_STRICT_DIRECT_MODE (OPTION_MD_BASE + 2)
256 {"strict-direct-mode", no_argument
, NULL
, OPTION_STRICT_DIRECT_MODE
},
258 #define OPTION_PRINT_INSN_SYNTAX (OPTION_MD_BASE + 3)
259 {"print-insn-syntax", no_argument
, NULL
, OPTION_PRINT_INSN_SYNTAX
},
261 #define OPTION_PRINT_OPCODES (OPTION_MD_BASE + 4)
262 {"print-opcodes", no_argument
, NULL
, OPTION_PRINT_OPCODES
},
264 #define OPTION_GENERATE_EXAMPLE (OPTION_MD_BASE + 5)
265 {"generate-example", no_argument
, NULL
, OPTION_GENERATE_EXAMPLE
},
267 {NULL
, no_argument
, NULL
, 0}
269 size_t md_longopts_size
= sizeof (md_longopts
);
271 /* Get the target cpu for the assembler. This is based on the configure
272 options and on the -m68hc11/-m68hc12 option. If no option is specified,
273 we must get the default. */
275 m68hc11_arch_format ()
277 get_default_target ();
278 if (current_architecture
& cpu6811
)
279 return "elf32-m68hc11";
281 return "elf32-m68hc12";
284 enum bfd_architecture
287 get_default_target ();
288 if (current_architecture
& cpu6811
)
289 return bfd_arch_m68hc11
;
291 return bfd_arch_m68hc12
;
301 md_show_usage (stream
)
304 get_default_target ();
305 fprintf (stream
, _("\
306 Motorola 68HC11/68HC12 options:\n\
307 -m68hc11 | -m68hc12 specify the processor [default %s]\n\
308 --force-long-branchs always turn relative branchs into absolute ones\n\
309 -S,--short-branchs do not turn relative branchs into absolute ones\n\
310 when the offset is out of range\n\
311 --strict-direct-mode do not turn the direct mode into extended mode\n\
312 when the instruction does not support direct mode\n\
313 --print-insn-syntax print the syntax of instruction in case of error\n\
314 --print-opcodes print the list of instructions with syntax\n\
315 --generate-example generate an example of each instruction\n\
316 (used for testing)\n"), default_cpu
);
320 /* Try to identify the default target based on the BFD library. */
322 get_default_target ()
324 const bfd_target
*target
;
327 if (current_architecture
!= 0)
330 default_cpu
= "unknown";
331 target
= bfd_find_target (0, &abfd
);
332 if (target
&& target
->name
)
334 if (strcmp (target
->name
, "elf32-m68hc12") == 0)
336 current_architecture
= cpu6812
;
337 default_cpu
= "m68hc12";
339 else if (strcmp (target
->name
, "elf32-m68hc11") == 0)
341 current_architecture
= cpu6811
;
342 default_cpu
= "m68hc11";
346 as_bad (_("Default target `%s' is not supported."), target
->name
);
352 m68hc11_print_statistics (file
)
356 struct m68hc11_opcode_def
*opc
;
358 hash_print_statistics (file
, "opcode table", m68hc11_hash
);
360 opc
= m68hc11_opcode_defs
;
361 if (opc
== 0 || m68hc11_nb_opcode_defs
== 0)
364 /* Dump the opcode statistics table. */
365 fprintf (file
, _("Name # Modes Min ops Max ops Modes mask # Used\n"));
366 for (i
= 0; i
< m68hc11_nb_opcode_defs
; i
++, opc
++)
368 fprintf (file
, "%-7.7s %5d %7d %7d 0x%08lx %7d\n",
371 opc
->min_operands
, opc
->max_operands
, opc
->format
, opc
->used
);
376 md_parse_option (c
, arg
)
380 get_default_target ();
383 /* -S means keep external to 2 bits offset rather than 16 bits one. */
384 case OPTION_SHORT_BRANCHS
:
386 flag_fixed_branchs
= 1;
389 case OPTION_FORCE_LONG_BRANCH
:
390 flag_force_long_jumps
= 1;
393 case OPTION_PRINT_INSN_SYNTAX
:
394 flag_print_insn_syntax
= 1;
397 case OPTION_PRINT_OPCODES
:
398 flag_print_opcodes
= 1;
401 case OPTION_STRICT_DIRECT_MODE
:
402 flag_strict_direct_addressing
= 0;
405 case OPTION_GENERATE_EXAMPLE
:
406 flag_print_opcodes
= 2;
410 if (strcasecmp (arg
, "68hc11") == 0)
411 current_architecture
= cpu6811
;
412 else if (strcasecmp (arg
, "68hc12") == 0)
413 current_architecture
= cpu6812
;
415 as_bad (_("Option `%s' is not recognized."), arg
);
426 md_undefined_symbol (name
)
427 char *name ATTRIBUTE_UNUSED
;
432 /* Equal to MAX_PRECISION in atof-ieee.c. */
433 #define MAX_LITTLENUMS 6
435 /* Turn a string in input_line_pointer into a floating point constant
436 of type TYPE, and store the appropriate bytes in *LITP. The number
437 of LITTLENUMS emitted is stored in *SIZEP. An error message is
438 returned, or NULL on OK. */
440 md_atof (type
, litP
, sizeP
)
446 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
447 LITTLENUM_TYPE
*wordP
;
478 return _("Bad call to MD_ATOF()");
480 t
= atof_ieee (input_line_pointer
, type
, words
);
482 input_line_pointer
= t
;
484 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
485 for (wordP
= words
; prec
--;)
487 md_number_to_chars (litP
, (long) (*wordP
++), sizeof (LITTLENUM_TYPE
));
488 litP
+= sizeof (LITTLENUM_TYPE
);
494 md_section_align (seg
, addr
)
498 int align
= bfd_get_section_alignment (stdoutput
, seg
);
499 return ((addr
+ (1 << align
) - 1) & (-1 << align
));
503 cmp_opcode (op1
, op2
)
504 struct m68hc11_opcode
*op1
;
505 struct m68hc11_opcode
*op2
;
507 return strcmp (op1
->name
, op2
->name
);
510 /* Initialize the assembler. Create the opcode hash table
511 (sorted on the names) with the M6811 opcode table
512 (from opcode library). */
516 char *prev_name
= "";
517 struct m68hc11_opcode
*opcodes
;
518 struct m68hc11_opcode_def
*opc
= 0;
521 get_default_target ();
523 m68hc11_hash
= hash_new ();
525 /* Get a writable copy of the opcode table and sort it on the names. */
526 opcodes
= (struct m68hc11_opcode
*) xmalloc (m68hc11_num_opcodes
*
529 m68hc11_sorted_opcodes
= opcodes
;
531 for (i
= 0; i
< m68hc11_num_opcodes
; i
++)
533 if (m68hc11_opcodes
[i
].arch
& current_architecture
)
535 opcodes
[num_opcodes
] = m68hc11_opcodes
[i
];
536 if (opcodes
[num_opcodes
].name
[0] == 'b'
537 && opcodes
[num_opcodes
].format
& M6811_OP_JUMP_REL
538 && !(opcodes
[num_opcodes
].format
& M6811_OP_BITMASK
))
541 opcodes
[num_opcodes
] = m68hc11_opcodes
[i
];
544 for (j
= 0; alias_opcodes
[j
].name
!= 0; j
++)
545 if (strcmp (m68hc11_opcodes
[i
].name
, alias_opcodes
[j
].name
) == 0)
547 opcodes
[num_opcodes
] = m68hc11_opcodes
[i
];
548 opcodes
[num_opcodes
].name
= alias_opcodes
[j
].alias
;
554 qsort (opcodes
, num_opcodes
, sizeof (struct m68hc11_opcode
), cmp_opcode
);
556 opc
= (struct m68hc11_opcode_def
*)
557 xmalloc (num_opcodes
* sizeof (struct m68hc11_opcode_def
));
558 m68hc11_opcode_defs
= opc
--;
560 /* Insert unique names into hash table. The M6811 instruction set
561 has several identical opcode names that have different opcodes based
562 on the operands. This hash table then provides a quick index to
563 the first opcode with a particular name in the opcode table. */
564 for (i
= 0; i
< num_opcodes
; i
++, opcodes
++)
568 if (strcmp (prev_name
, opcodes
->name
))
570 prev_name
= (char *) opcodes
->name
;
574 opc
->min_operands
= 100;
575 opc
->max_operands
= 0;
577 opc
->opcode
= opcodes
;
579 hash_insert (m68hc11_hash
, opcodes
->name
, (char *) opc
);
582 opc
->format
|= opcodes
->format
;
584 /* See how many operands this opcode needs. */
586 if (opcodes
->format
& M6811_OP_MASK
)
588 if (opcodes
->format
& M6811_OP_BITMASK
)
590 if (opcodes
->format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
592 if (opcodes
->format
& (M6812_OP_IND16_P2
| M6812_OP_IDX_P2
))
595 if (expect
< opc
->min_operands
)
596 opc
->min_operands
= expect
;
597 if (expect
> opc
->max_operands
)
598 opc
->max_operands
= expect
;
601 m68hc11_nb_opcode_defs
= opc
- m68hc11_opcode_defs
;
603 if (flag_print_opcodes
)
605 print_opcode_list ();
611 m68hc11_init_after_args ()
617 /* Return a string that represents the operand format for the instruction.
618 When example is true, this generates an example of operand. This is used
619 to give an example and also to generate a test. */
621 print_opcode_format (opcode
, example
)
622 struct m68hc11_opcode
*opcode
;
625 static char buf
[128];
626 int format
= opcode
->format
;
631 if (format
& M6811_OP_IMM8
)
634 sprintf (p
, "#%d", rand () & 0x0FF);
636 strcpy (p
, _("#<imm8>"));
640 if (format
& M6811_OP_IMM16
)
643 sprintf (p
, "#%d", rand () & 0x0FFFF);
645 strcpy (p
, _("#<imm16>"));
649 if (format
& M6811_OP_IX
)
652 sprintf (p
, "%d,X", rand () & 0x0FF);
654 strcpy (p
, _("<imm8>,X"));
658 if (format
& M6811_OP_IY
)
661 sprintf (p
, "%d,X", rand () & 0x0FF);
663 strcpy (p
, _("<imm8>,X"));
667 if (format
& M6812_OP_IDX
)
670 sprintf (p
, "%d,X", rand () & 0x0FF);
676 if (format
& M6811_OP_DIRECT
)
679 sprintf (p
, "*Z%d", rand () & 0x0FF);
681 strcpy (p
, _("*<abs8>"));
685 if (format
& M6811_OP_BITMASK
)
691 sprintf (p
, "#$%02x", rand () & 0x0FF);
693 strcpy (p
, _("#<mask>"));
696 if (format
& M6811_OP_JUMP_REL
)
700 if (format
& M6811_OP_IND16
)
703 sprintf (p
, _("symbol%d"), rand () & 0x0FF);
705 strcpy (p
, _("<abs>"));
710 if (format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
714 if (format
& M6811_OP_BITMASK
)
716 sprintf (p
, ".+%d", rand () & 0x7F);
720 sprintf (p
, "L%d", rand () & 0x0FF);
724 strcpy (p
, _("<label>"));
730 /* Prints the list of instructions with the possible operands. */
735 char *prev_name
= "";
736 struct m68hc11_opcode
*opcodes
;
737 int example
= flag_print_opcodes
== 2;
740 printf (_("# Example of `%s' instructions\n\t.sect .text\n_start:\n"),
743 opcodes
= m68hc11_sorted_opcodes
;
745 /* Walk the list sorted on names (by md_begin). We only report
746 one instruction per line, and we collect the different operand
748 for (i
= 0; i
< num_opcodes
; i
++, opcodes
++)
750 char *fmt
= print_opcode_format (opcodes
, example
);
754 printf ("L%d:\t", i
);
755 printf ("%s %s\n", opcodes
->name
, fmt
);
759 if (strcmp (prev_name
, opcodes
->name
))
764 printf ("%-5.5s ", opcodes
->name
);
765 prev_name
= (char *) opcodes
->name
;
768 printf (" [%s]", fmt
);
774 /* Print the instruction format. This operation is called when some
775 instruction is not correct. Instruction format is printed as an
778 print_insn_format (name
)
781 struct m68hc11_opcode_def
*opc
;
782 struct m68hc11_opcode
*opcode
;
785 opc
= (struct m68hc11_opcode_def
*) hash_find (m68hc11_hash
, name
);
788 as_bad (_("Instruction `%s' is not recognized."), name
);
791 opcode
= opc
->opcode
;
793 as_bad (_("Instruction formats for `%s':"), name
);
798 fmt
= print_opcode_format (opcode
, 0, 0);
799 sprintf (buf
, "\t%-5.5s %s", opcode
->name
, fmt
);
804 while (strcmp (opcode
->name
, name
) == 0);
807 /* Analysis of 68HC11 and 68HC12 operands. */
809 /* reg_name_search() finds the register number given its name.
810 Returns the register number or REG_NONE on failure. */
812 reg_name_search (name
)
815 if (strcasecmp (name
, "x") == 0 || strcasecmp (name
, "ix") == 0)
817 if (strcasecmp (name
, "y") == 0 || strcasecmp (name
, "iy") == 0)
819 if (strcasecmp (name
, "a") == 0)
821 if (strcasecmp (name
, "b") == 0)
823 if (strcasecmp (name
, "d") == 0)
825 if (strcasecmp (name
, "sp") == 0)
827 if (strcasecmp (name
, "pc") == 0)
829 if (strcasecmp (name
, "ccr") == 0)
839 while (*p
== ' ' || *p
== '\t')
845 /* Check the string at input_line_pointer
846 to see if it is a valid register name. */
850 register_id reg_number
;
851 char c
, *p
= input_line_pointer
;
853 if (!is_name_beginner (*p
++))
856 while (is_part_of_name (*p
++))
863 /* Look to see if it's in the register table. */
864 reg_number
= reg_name_search (input_line_pointer
);
865 if (reg_number
!= REG_NONE
)
870 input_line_pointer
= p
;
879 /* Parse a string of operands and return an array of expressions.
881 Operand mode[0] mode[1] exp[0] exp[1]
882 #n M6811_OP_IMM16 - O_*
883 *<exp> M6811_OP_DIRECT - O_*
884 .{+-}<exp> M6811_OP_JUMP_REL - O_*
885 <exp> M6811_OP_IND16 - O_*
886 ,r N,r M6812_OP_IDX M6812_OP_REG O_constant O_register
887 n,-r M6812_PRE_DEC M6812_OP_REG O_constant O_register
888 n,+r M6812_PRE_INC " "
889 n,r- M6812_POST_DEC " "
890 n,r+ M6812_POST_INC " "
891 A,r B,r D,r M6811_OP_REG M6812_OP_REG O_register O_register
892 [D,r] M6811_OP_IDX_2 M6812_OP_REG O_register O_register
893 [n,r] M6811_OP_IDX_1 M6812_OP_REG O_constant O_register */
895 get_operand (oper
, which
, opmode
)
900 char *p
= input_line_pointer
;
904 oper
->exp
.X_op
= O_absent
;
905 oper
->reg1
= REG_NONE
;
906 oper
->reg2
= REG_NONE
;
907 mode
= M6811_OP_NONE
;
911 if (*p
== 0 || *p
== '\n' || *p
== '\r')
913 input_line_pointer
= p
;
917 if (*p
== '*' && (opmode
& (M6811_OP_DIRECT
| M6811_OP_IND16
)))
919 mode
= M6811_OP_DIRECT
;
924 if (!(opmode
& (M6811_OP_IMM8
| M6811_OP_IMM16
| M6811_OP_BITMASK
)))
926 as_bad (_("Immediate operand is not allowed for operand %d."),
931 mode
= M6811_OP_IMM16
;
933 if (strncmp (p
, "%hi", 3) == 0)
936 mode
|= M6811_OP_HIGH_ADDR
;
938 else if (strncmp (p
, "%lo", 3) == 0)
941 mode
|= M6811_OP_LOW_ADDR
;
944 else if (*p
== '.' && (p
[1] == '+' || p
[1] == '-'))
947 mode
= M6811_OP_JUMP_REL
;
951 if (current_architecture
& cpu6811
)
952 as_bad (_("Indirect indexed addressing is not valid for 68HC11."));
955 mode
= M6812_OP_IDX_2
;
958 else if (*p
== ',') /* Special handling of ,x and ,y. */
961 input_line_pointer
= p
;
963 reg
= register_name ();
967 oper
->exp
.X_op
= O_constant
;
968 oper
->exp
.X_add_number
= 0;
969 oper
->mode
= M6812_OP_IDX
;
972 as_bad (_("Spurious `,' or bad indirect register addressing mode."));
975 input_line_pointer
= p
;
977 if (mode
== M6811_OP_NONE
|| mode
== M6812_OP_IDX_2
)
978 reg
= register_name ();
984 p
= skip_whites (input_line_pointer
);
985 if (*p
== ']' && mode
== M6812_OP_IDX_2
)
988 (_("Missing second register or offset for indexed-indirect mode."));
993 oper
->mode
= mode
| M6812_OP_REG
;
996 if (mode
== M6812_OP_IDX_2
)
998 as_bad (_("Missing second register for indexed-indirect mode."));
1005 input_line_pointer
= p
;
1006 reg
= register_name ();
1007 if (reg
!= REG_NONE
)
1009 p
= skip_whites (input_line_pointer
);
1010 if (mode
== M6812_OP_IDX_2
)
1014 as_bad (_("Missing `]' to close indexed-indirect mode."));
1019 input_line_pointer
= p
;
1027 /* In MRI mode, isolate the operand because we can't distinguish
1028 operands from comments. */
1033 p
= skip_whites (p
);
1034 while (*p
&& *p
!= ' ' && *p
!= '\t')
1043 /* Parse as an expression. */
1044 expression (&oper
->exp
);
1053 expression (&oper
->exp
);
1056 if (oper
->exp
.X_op
== O_illegal
)
1058 as_bad (_("Illegal operand."));
1061 else if (oper
->exp
.X_op
== O_absent
)
1063 as_bad (_("Missing operand."));
1067 p
= input_line_pointer
;
1069 if (mode
== M6811_OP_NONE
|| mode
== M6811_OP_DIRECT
1070 || mode
== M6812_OP_IDX_2
)
1072 p
= skip_whites (input_line_pointer
);
1076 int possible_mode
= M6811_OP_NONE
;
1077 char *old_input_line
;
1080 /* 68HC12 pre increment or decrement. */
1081 if (mode
== M6811_OP_NONE
)
1085 possible_mode
= M6812_PRE_DEC
;
1090 possible_mode
= M6812_PRE_INC
;
1093 p
= skip_whites (p
);
1095 old_input_line
= input_line_pointer
;
1096 input_line_pointer
= p
;
1097 reg
= register_name ();
1099 /* Backtrack if we have a valid constant expression and
1100 it does not correspond to the offset of the 68HC12 indexed
1101 addressing mode (as in N,x). */
1102 if (reg
== REG_NONE
&& mode
== M6811_OP_NONE
1103 && possible_mode
!= M6811_OP_NONE
)
1105 oper
->mode
= M6811_OP_IND16
| M6811_OP_JUMP_REL
;
1106 input_line_pointer
= skip_whites (old_input_line
);
1110 if (possible_mode
!= M6811_OP_NONE
)
1111 mode
= possible_mode
;
1113 if ((current_architecture
& cpu6811
)
1114 && possible_mode
!= M6811_OP_NONE
)
1115 as_bad (_("Pre-increment mode is not valid for 68HC11"));
1117 if (which
== 0 && opmode
& M6812_OP_IDX_P2
1118 && reg
!= REG_X
&& reg
!= REG_Y
1119 && reg
!= REG_PC
&& reg
!= REG_SP
)
1122 input_line_pointer
= p
;
1125 if (reg
== REG_NONE
&& mode
!= M6811_OP_DIRECT
1126 && !(mode
== M6811_OP_NONE
&& opmode
& M6811_OP_IND16
))
1128 as_bad (_("Wrong register in register indirect mode."));
1131 if (mode
== M6812_OP_IDX_2
)
1133 p
= skip_whites (input_line_pointer
);
1136 as_bad (_("Missing `]' to close register indirect operand."));
1139 input_line_pointer
= p
;
1141 if (reg
!= REG_NONE
)
1144 if (mode
== M6811_OP_NONE
)
1146 p
= input_line_pointer
;
1149 mode
= M6812_POST_DEC
;
1151 if (current_architecture
& cpu6811
)
1153 (_("Post-decrement mode is not valid for 68HC11."));
1157 mode
= M6812_POST_INC
;
1159 if (current_architecture
& cpu6811
)
1161 (_("Post-increment mode is not valid for 68HC11."));
1164 mode
= M6812_OP_IDX
;
1166 input_line_pointer
= p
;
1169 mode
|= M6812_OP_IDX
;
1176 if (mode
== M6812_OP_D_IDX_2
)
1178 as_bad (_("Invalid indexed indirect mode."));
1183 /* If the mode is not known until now, this is either a label
1184 or an indirect address. */
1185 if (mode
== M6811_OP_NONE
)
1186 mode
= M6811_OP_IND16
| M6811_OP_JUMP_REL
;
1188 p
= input_line_pointer
;
1189 while (*p
== ' ' || *p
== '\t')
1191 input_line_pointer
= p
;
1197 #define M6812_AUTO_INC_DEC (M6812_PRE_INC | M6812_PRE_DEC \
1198 | M6812_POST_INC | M6812_POST_DEC)
1200 /* Checks that the number 'num' fits for a given mode. */
1202 check_range (num
, mode
)
1206 /* Auto increment and decrement are ok for [-8..8] without 0. */
1207 if (mode
& M6812_AUTO_INC_DEC
)
1208 return (num
!= 0 && num
<= 8 && num
>= -8);
1210 /* The 68HC12 supports 5, 9 and 16-bits offsets. */
1211 if (mode
& (M6812_INDEXED_IND
| M6812_INDEXED
| M6812_OP_IDX
))
1212 mode
= M6811_OP_IND16
;
1214 if (mode
& M6812_OP_JUMP_REL16
)
1215 mode
= M6811_OP_IND16
;
1221 case M6811_OP_DIRECT
:
1222 return (num
>= 0 && num
<= 255) ? 1 : 0;
1224 case M6811_OP_BITMASK
:
1226 return (((num
& 0xFFFFFF00) == 0) || ((num
& 0xFFFFFF00) == 0xFFFFFF00))
1229 case M6811_OP_JUMP_REL
:
1230 return (num
>= -128 && num
<= 127) ? 1 : 0;
1232 case M6811_OP_IND16
:
1233 case M6811_OP_IMM16
:
1234 return (((num
& 0xFFFF0000) == 0) || ((num
& 0xFFFF0000) == 0xFFFF0000))
1237 case M6812_OP_IBCC_MARKER
:
1238 case M6812_OP_TBCC_MARKER
:
1239 case M6812_OP_DBCC_MARKER
:
1240 return (num
>= -256 && num
<= 255) ? 1 : 0;
1242 case M6812_OP_TRAP_ID
:
1243 return ((num
>= 0x30 && num
<= 0x39)
1244 || (num
>= 0x40 && num
<= 0x0ff)) ? 1 : 0;
1251 /* Gas fixup generation. */
1253 /* Put a 1 byte expression described by 'oper'. If this expression contains
1254 unresolved symbols, generate an 8-bit fixup. */
1256 fixup8 (oper
, mode
, opmode
)
1265 if (oper
->X_op
== O_constant
)
1267 if (mode
& M6812_OP_TRAP_ID
1268 && !check_range (oper
->X_add_number
, M6812_OP_TRAP_ID
))
1270 static char trap_id_warn_once
= 0;
1272 as_bad (_("Trap id `%ld' is out of range."), oper
->X_add_number
);
1273 if (trap_id_warn_once
== 0)
1275 trap_id_warn_once
= 1;
1276 as_bad (_("Trap id must be within [0x30..0x39] or [0x40..0xff]."));
1280 if (!(mode
& M6812_OP_TRAP_ID
)
1281 && !check_range (oper
->X_add_number
, mode
))
1283 as_bad (_("Operand out of 8-bit range: `%ld'."), oper
->X_add_number
);
1285 number_to_chars_bigendian (f
, oper
->X_add_number
& 0x0FF, 1);
1287 else if (oper
->X_op
!= O_register
)
1289 if (mode
& M6812_OP_TRAP_ID
)
1290 as_bad (_("The trap id must be a constant."));
1292 if (mode
== M6811_OP_JUMP_REL
)
1296 fixp
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 1,
1297 oper
, true, BFD_RELOC_8_PCREL
);
1298 fixp
->fx_pcrel_adjust
= 1;
1302 /* Now create an 8-bit fixup. If there was some %hi or %lo
1303 modifier, generate the reloc accordingly. */
1304 fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 1,
1306 ((opmode
& M6811_OP_HIGH_ADDR
)
1307 ? BFD_RELOC_M68HC11_HI8
1308 : ((opmode
& M6811_OP_LOW_ADDR
)
1309 ? BFD_RELOC_M68HC11_LO8
: BFD_RELOC_8
)));
1311 number_to_chars_bigendian (f
, 0, 1);
1315 as_fatal (_("Operand `%x' not recognized in fixup8."), oper
->X_op
);
1319 /* Put a 2 bytes expression described by 'oper'. If this expression contains
1320 unresolved symbols, generate a 16-bit fixup. */
1322 fixup16 (oper
, mode
, opmode
)
1325 int opmode ATTRIBUTE_UNUSED
;
1331 if (oper
->X_op
== O_constant
)
1333 if (!check_range (oper
->X_add_number
, mode
))
1335 as_bad (_("Operand out of 16-bit range: `%ld'."),
1336 oper
->X_add_number
);
1338 number_to_chars_bigendian (f
, oper
->X_add_number
& 0x0FFFF, 2);
1340 else if (oper
->X_op
!= O_register
)
1344 /* Now create a 16-bit fixup. */
1345 fixp
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 2,
1347 (mode
& M6812_OP_JUMP_REL16
? true : false),
1348 (mode
& M6812_OP_JUMP_REL16
1349 ? BFD_RELOC_16_PCREL
: BFD_RELOC_16
));
1350 number_to_chars_bigendian (f
, 0, 2);
1351 if (mode
& M6812_OP_JUMP_REL16
)
1352 fixp
->fx_pcrel_adjust
= 2;
1356 as_fatal (_("Operand `%x' not recognized in fixup16."), oper
->X_op
);
1360 /* 68HC11 and 68HC12 code generation. */
1362 /* Translate the short branch/bsr instruction into a long branch. */
1363 static unsigned char
1364 convert_branch (code
)
1367 if (IS_OPCODE (code
, M6812_BSR
))
1369 else if (IS_OPCODE (code
, M6811_BSR
))
1371 else if (IS_OPCODE (code
, M6811_BRA
))
1372 return (current_architecture
& cpu6812
) ? M6812_JMP
: M6811_JMP
;
1374 as_fatal (_("Unexpected branch conversion with `%x'"), code
);
1376 /* Keep gcc happy. */
1380 /* Start a new insn that contains at least 'size' bytes. Record the
1381 line information of that insn in the dwarf2 debug sections. */
1383 m68hc11_new_insn (size
)
1388 f
= frag_more (size
);
1390 dwarf2_emit_insn (size
);
1395 /* Builds a jump instruction (bra, bcc, bsr). */
1397 build_jump_insn (opcode
, operands
, nb_operands
, jmp_mode
)
1398 struct m68hc11_opcode
*opcode
;
1408 /* The relative branch convertion is not supported for
1410 assert ((opcode
->format
& M6811_OP_BITMASK
) == 0);
1411 assert (nb_operands
== 1);
1412 assert (operands
[0].reg1
== REG_NONE
&& operands
[0].reg2
== REG_NONE
);
1414 code
= opcode
->opcode
;
1417 n
= operands
[0].exp
.X_add_number
;
1419 /* Turn into a long branch:
1420 - when force long branch option (and not for jbcc pseudos),
1421 - when jbcc and the constant is out of -128..127 range,
1422 - when branch optimization is allowed and branch out of range. */
1423 if ((jmp_mode
== 0 && flag_force_long_jumps
)
1424 || (operands
[0].exp
.X_op
== O_constant
1425 && (!check_range (n
, opcode
->format
) &&
1426 (jmp_mode
== 1 || flag_fixed_branchs
== 0))))
1428 if (code
== M6811_BSR
|| code
== M6811_BRA
|| code
== M6812_BSR
)
1430 code
= convert_branch (code
);
1432 f
= m68hc11_new_insn (1);
1433 number_to_chars_bigendian (f
, code
, 1);
1435 else if (current_architecture
& cpu6812
)
1437 /* 68HC12: translate the bcc into a lbcc. */
1438 f
= m68hc11_new_insn (2);
1439 number_to_chars_bigendian (f
, M6811_OPCODE_PAGE2
, 1);
1440 number_to_chars_bigendian (f
+ 1, code
, 1);
1441 fixup16 (&operands
[0].exp
, M6812_OP_JUMP_REL16
,
1442 M6812_OP_JUMP_REL16
);
1447 /* 68HC11: translate the bcc into b!cc +3; jmp <L>. */
1448 f
= m68hc11_new_insn (3);
1450 number_to_chars_bigendian (f
, code
, 1);
1451 number_to_chars_bigendian (f
+ 1, 3, 1);
1452 number_to_chars_bigendian (f
+ 2, M6811_JMP
, 1);
1454 fixup16 (&operands
[0].exp
, M6811_OP_IND16
, M6811_OP_IND16
);
1458 /* Branch with a constant that must fit in 8-bits. */
1459 if (operands
[0].exp
.X_op
== O_constant
)
1461 if (!check_range (n
, opcode
->format
))
1463 as_bad (_("Operand out of range for a relative branch: `%ld'"),
1466 else if (opcode
->format
& M6812_OP_JUMP_REL16
)
1468 f
= m68hc11_new_insn (4);
1469 number_to_chars_bigendian (f
, M6811_OPCODE_PAGE2
, 1);
1470 number_to_chars_bigendian (f
+ 1, code
, 1);
1471 number_to_chars_bigendian (f
+ 2, n
& 0x0ffff, 2);
1475 f
= m68hc11_new_insn (2);
1476 number_to_chars_bigendian (f
, code
, 1);
1477 number_to_chars_bigendian (f
+ 1, n
& 0x0FF, 1);
1480 else if (opcode
->format
& M6812_OP_JUMP_REL16
)
1482 f
= m68hc11_new_insn (2);
1483 number_to_chars_bigendian (f
, M6811_OPCODE_PAGE2
, 1);
1484 number_to_chars_bigendian (f
+ 1, code
, 1);
1485 fixup16 (&operands
[0].exp
, M6812_OP_JUMP_REL16
, M6812_OP_JUMP_REL16
);
1491 /* Branch offset must fit in 8-bits, don't do some relax. */
1492 if (jmp_mode
== 0 && flag_fixed_branchs
)
1494 opcode
= m68hc11_new_insn (1);
1495 number_to_chars_bigendian (opcode
, code
, 1);
1496 fixup8 (&operands
[0].exp
, M6811_OP_JUMP_REL
, M6811_OP_JUMP_REL
);
1499 /* bra/bsr made be changed into jmp/jsr. */
1500 else if (code
== M6811_BSR
|| code
== M6811_BRA
|| code
== M6812_BSR
)
1502 opcode
= m68hc11_new_insn (2);
1503 number_to_chars_bigendian (opcode
, code
, 1);
1504 number_to_chars_bigendian (opcode
+ 1, 0, 1);
1505 frag_var (rs_machine_dependent
, 2, 1,
1506 ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_UNDF
),
1507 operands
[0].exp
.X_add_symbol
, (offsetT
) n
, opcode
);
1509 else if (current_architecture
& cpu6812
)
1511 opcode
= m68hc11_new_insn (2);
1512 number_to_chars_bigendian (opcode
, code
, 1);
1513 number_to_chars_bigendian (opcode
+ 1, 0, 1);
1514 frag_var (rs_machine_dependent
, 2, 2,
1515 ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
, STATE_UNDF
),
1516 operands
[0].exp
.X_add_symbol
, (offsetT
) n
, opcode
);
1520 opcode
= m68hc11_new_insn (2);
1521 number_to_chars_bigendian (opcode
, code
, 1);
1522 number_to_chars_bigendian (opcode
+ 1, 0, 1);
1523 frag_var (rs_machine_dependent
, 3, 3,
1524 ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
, STATE_UNDF
),
1525 operands
[0].exp
.X_add_symbol
, (offsetT
) n
, opcode
);
1530 /* Builds a dbne/dbeq/tbne/tbeq instruction. */
1532 build_dbranch_insn (opcode
, operands
, nb_operands
, jmp_mode
)
1533 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;
1552 f
= m68hc11_new_insn (1);
1553 number_to_chars_bigendian (f
, code
, 1);
1555 n
= operands
[1].exp
.X_add_number
;
1556 code
= operands
[0].reg1
;
1558 if (operands
[0].reg1
== REG_NONE
|| operands
[0].reg1
== REG_CCR
1559 || operands
[0].reg1
== REG_PC
)
1560 as_bad (_("Invalid register for dbcc/tbcc instruction."));
1562 if (opcode
->format
& M6812_OP_IBCC_MARKER
)
1564 else if (opcode
->format
& M6812_OP_TBCC_MARKER
)
1567 if (!(opcode
->format
& M6812_OP_EQ_MARKER
))
1570 /* Turn into a long branch:
1571 - when force long branch option (and not for jbcc pseudos),
1572 - when jdbcc and the constant is out of -256..255 range,
1573 - when branch optimization is allowed and branch out of range. */
1574 if ((jmp_mode
== 0 && flag_force_long_jumps
)
1575 || (operands
[1].exp
.X_op
== O_constant
1576 && (!check_range (n
, M6812_OP_IBCC_MARKER
) &&
1577 (jmp_mode
== 1 || flag_fixed_branchs
== 0))))
1581 number_to_chars_bigendian (f
, code
, 1);
1582 number_to_chars_bigendian (f
+ 1, M6812_JMP
, 1);
1583 fixup16 (&operands
[0].exp
, M6811_OP_IND16
, M6811_OP_IND16
);
1587 /* Branch with a constant that must fit in 9-bits. */
1588 if (operands
[1].exp
.X_op
== O_constant
)
1590 if (!check_range (n
, M6812_OP_IBCC_MARKER
))
1592 as_bad (_("Operand out of range for a relative branch: `%ld'"),
1601 number_to_chars_bigendian (f
, code
, 1);
1602 number_to_chars_bigendian (f
+ 1, n
& 0x0FF, 1);
1607 /* Branch offset must fit in 8-bits, don't do some relax. */
1608 if (jmp_mode
== 0 && flag_fixed_branchs
)
1610 fixup8 (&operands
[0].exp
, M6811_OP_JUMP_REL
, M6811_OP_JUMP_REL
);
1616 number_to_chars_bigendian (f
, code
, 1);
1617 number_to_chars_bigendian (f
+ 1, 0, 1);
1618 frag_var (rs_machine_dependent
, 3, 3,
1619 ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_UNDF
),
1620 operands
[1].exp
.X_add_symbol
, (offsetT
) n
, f
);
1625 #define OP_EXTENDED (M6811_OP_PAGE2 | M6811_OP_PAGE3 | M6811_OP_PAGE4)
1627 /* Assemble the post index byte for 68HC12 extended addressing modes. */
1629 build_indexed_byte (op
, format
, move_insn
)
1631 int format ATTRIBUTE_UNUSED
;
1634 unsigned char byte
= 0;
1639 val
= op
->exp
.X_add_number
;
1641 if (mode
& M6812_AUTO_INC_DEC
)
1644 if (mode
& (M6812_POST_INC
| M6812_POST_DEC
))
1647 if (op
->exp
.X_op
== O_constant
)
1649 if (!check_range (val
, mode
))
1651 as_bad (_("Increment/decrement value is out of range: `%ld'."),
1654 if (mode
& (M6812_POST_INC
| M6812_PRE_INC
))
1655 byte
|= (val
- 1) & 0x07;
1657 byte
|= (8 - ((val
) & 7)) | 0x8;
1662 as_fatal (_("Expecting a register."));
1677 as_bad (_("Invalid register for post/pre increment."));
1682 number_to_chars_bigendian (f
, byte
, 1);
1686 if (mode
& M6812_OP_IDX
)
1707 as_bad (_("Invalid register."));
1710 if (op
->exp
.X_op
== O_constant
)
1712 if (!check_range (val
, M6812_OP_IDX
))
1714 as_bad (_("Offset out of 16-bit range: %ld."), val
);
1717 if (move_insn
&& !(val
>= -16 && val
<= 15))
1719 as_bad (_("Offset out of 5-bit range for movw/movb insn: %ld."),
1724 if (val
>= -16 && val
<= 15 && !(mode
& M6812_OP_IDX_2
))
1729 number_to_chars_bigendian (f
, byte
, 1);
1732 else if (val
>= -256 && val
<= 255 && !(mode
& M6812_OP_IDX_2
))
1739 number_to_chars_bigendian (f
, byte
, 1);
1740 number_to_chars_bigendian (f
+ 1, val
& 0x0FF, 1);
1746 if (mode
& M6812_OP_IDX_2
)
1752 number_to_chars_bigendian (f
, byte
, 1);
1753 number_to_chars_bigendian (f
+ 1, val
& 0x0FFFF, 2);
1758 number_to_chars_bigendian (f
, byte
, 1);
1760 fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 2,
1761 &op
->exp
, false, BFD_RELOC_16
);
1763 frag_var (rs_machine_dependent
, 2, 2,
1764 ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_UNDF
),
1765 op
->exp
.X_add_symbol
, val
, f
);
1769 if (mode
& M6812_OP_REG
)
1771 if (mode
& M6812_OP_IDX_2
)
1773 if (op
->reg1
!= REG_D
)
1774 as_bad (_("Expecting register D for indexed indirect mode."));
1776 as_bad (_("Indexed indirect mode is not allowed for movb/movw."));
1793 as_bad (_("Invalid accumulator register."));
1818 as_bad (_("Invalid indexed register."));
1822 number_to_chars_bigendian (f
, byte
, 1);
1826 as_fatal (_("Addressing mode not implemented yet."));
1830 /* Assemble the 68HC12 register mode byte. */
1832 build_reg_mode (op
, format
)
1839 if (format
& M6812_OP_SEX_MARKER
1840 && op
->reg1
!= REG_A
&& op
->reg1
!= REG_B
&& op
->reg1
!= REG_CCR
)
1841 as_bad (_("Invalid source register for this instruction, use 'tfr'."));
1842 else if (op
->reg1
== REG_NONE
|| op
->reg1
== REG_PC
)
1843 as_bad (_("Invalid source register."));
1845 if (format
& M6812_OP_SEX_MARKER
1846 && op
->reg2
!= REG_D
1847 && op
->reg2
!= REG_X
&& op
->reg2
!= REG_Y
&& op
->reg2
!= REG_SP
)
1848 as_bad (_("Invalid destination register for this instruction, use 'tfr'."));
1849 else if (op
->reg2
== REG_NONE
|| op
->reg2
== REG_PC
)
1850 as_bad (_("Invalid destination register."));
1852 byte
= (op
->reg1
<< 4) | (op
->reg2
);
1853 if (format
& M6812_OP_EXG_MARKER
)
1857 number_to_chars_bigendian (f
, byte
, 1);
1861 /* build_insn takes a pointer to the opcode entry in the opcode table,
1862 the array of operand expressions and builds the correspding instruction.
1863 This operation only deals with non relative jumps insn (need special
1866 build_insn (opcode
, operands
, nb_operands
)
1867 struct m68hc11_opcode
*opcode
;
1869 int nb_operands ATTRIBUTE_UNUSED
;
1877 /* Put the page code instruction if there is one. */
1878 format
= opcode
->format
;
1879 if (format
& OP_EXTENDED
)
1883 f
= m68hc11_new_insn (2);
1884 if (format
& M6811_OP_PAGE2
)
1885 page_code
= M6811_OPCODE_PAGE2
;
1886 else if (format
& M6811_OP_PAGE3
)
1887 page_code
= M6811_OPCODE_PAGE3
;
1889 page_code
= M6811_OPCODE_PAGE4
;
1891 number_to_chars_bigendian (f
, page_code
, 1);
1896 f
= m68hc11_new_insn (1);
1898 number_to_chars_bigendian (f
, opcode
->opcode
, 1);
1902 /* The 68HC12 movb and movw instructions are special. We have to handle
1903 them in a special way. */
1904 if (format
& (M6812_OP_IND16_P2
| M6812_OP_IDX_P2
))
1907 if (format
& M6812_OP_IDX
)
1909 insn_size
+= build_indexed_byte (&operands
[0], format
, 1);
1911 format
&= ~M6812_OP_IDX
;
1913 if (format
& M6812_OP_IDX_P2
)
1915 insn_size
+= build_indexed_byte (&operands
[1], format
, 1);
1917 format
&= ~M6812_OP_IDX_P2
;
1921 if (format
& (M6811_OP_DIRECT
| M6811_OP_IMM8
))
1924 fixup8 (&operands
[i
].exp
,
1925 format
& (M6811_OP_DIRECT
| M6811_OP_IMM8
| M6812_OP_TRAP_ID
),
1929 else if (format
& (M6811_OP_IMM16
| M6811_OP_IND16
))
1932 fixup16 (&operands
[i
].exp
, format
& (M6811_OP_IMM16
| M6811_OP_IND16
),
1936 else if (format
& (M6811_OP_IX
| M6811_OP_IY
))
1938 if ((format
& M6811_OP_IX
) && (operands
[0].reg1
!= REG_X
))
1939 as_bad (_("Invalid indexed register, expecting register X."));
1940 if ((format
& M6811_OP_IY
) && (operands
[0].reg1
!= REG_Y
))
1941 as_bad (_("Invalid indexed register, expecting register Y."));
1944 fixup8 (&operands
[0].exp
, M6811_OP_IX
, operands
[0].mode
);
1948 (M6812_OP_IDX
| M6812_OP_IDX_2
| M6812_OP_IDX_1
| M6812_OP_D_IDX
))
1950 insn_size
+= build_indexed_byte (&operands
[i
], format
, move_insn
);
1953 else if (format
& M6812_OP_REG
&& current_architecture
& cpu6812
)
1955 insn_size
+= build_reg_mode (&operands
[i
], format
);
1958 if (format
& M6811_OP_BITMASK
)
1961 fixup8 (&operands
[i
].exp
, M6811_OP_BITMASK
, operands
[i
].mode
);
1964 if (format
& M6811_OP_JUMP_REL
)
1967 fixup8 (&operands
[i
].exp
, M6811_OP_JUMP_REL
, operands
[i
].mode
);
1970 else if (format
& M6812_OP_IND16_P2
)
1973 fixup16 (&operands
[1].exp
, M6811_OP_IND16
, operands
[1].mode
);
1977 /* Opcode identification and operand analysis. */
1979 /* find() gets a pointer to an entry in the opcode table. It must look at all
1980 opcodes with the same name and use the operands to choose the correct
1981 opcode. Returns the opcode pointer if there was a match and 0 if none. */
1982 static struct m68hc11_opcode
*
1983 find (opc
, operands
, nb_operands
)
1984 struct m68hc11_opcode_def
*opc
;
1989 struct m68hc11_opcode
*opcode
;
1990 struct m68hc11_opcode
*op_indirect
;
1993 opcode
= opc
->opcode
;
1995 /* Now search the opcode table table for one with operands
1996 that matches what we've got. We're only done if the operands matched so
1997 far AND there are no more to check. */
1998 for (pos
= match
= 0; match
== 0 && pos
< opc
->nb_modes
; pos
++, opcode
++)
2000 int poss_indirect
= 0;
2001 long format
= opcode
->format
;
2005 if (opcode
->format
& M6811_OP_MASK
)
2007 if (opcode
->format
& M6811_OP_BITMASK
)
2009 if (opcode
->format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
2011 if (opcode
->format
& (M6812_OP_IND16_P2
| M6812_OP_IDX_P2
))
2014 for (i
= 0; expect
== nb_operands
&& i
< nb_operands
; i
++)
2016 int mode
= operands
[i
].mode
;
2018 if (mode
& M6811_OP_IMM16
)
2021 (M6811_OP_IMM8
| M6811_OP_IMM16
| M6811_OP_BITMASK
))
2025 if (mode
== M6811_OP_DIRECT
)
2027 if (format
& M6811_OP_DIRECT
)
2030 /* If the operand is a page 0 operand, remember a
2031 possible <abs-16> addressing mode. We mark
2032 this and continue to check other operands. */
2033 if (format
& M6811_OP_IND16
2034 && flag_strict_direct_addressing
&& op_indirect
== 0)
2041 if (mode
& M6811_OP_IND16
)
2043 if (i
== 0 && (format
& M6811_OP_IND16
) != 0)
2045 if (i
!= 0 && (format
& M6812_OP_IND16_P2
) != 0)
2047 if (i
== 0 && (format
& M6811_OP_BITMASK
))
2050 if (mode
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
2052 if (format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
2055 if (mode
& M6812_OP_REG
)
2058 && (format
& M6812_OP_REG
)
2059 && (operands
[i
].reg2
== REG_NONE
))
2062 && (format
& M6812_OP_REG
)
2063 && (format
& M6812_OP_REG_2
)
2064 && (operands
[i
].reg2
!= REG_NONE
))
2067 && (format
& M6812_OP_IDX
)
2068 && (operands
[i
].reg2
!= REG_NONE
))
2071 && (format
& M6812_OP_D_IDX
))
2074 && (format
& M6812_OP_IDX
)
2075 && (format
& (M6812_OP_IND16_P2
| M6812_OP_IDX_P2
)))
2078 && (format
& M6812_OP_IDX_P2
))
2082 if (mode
& M6812_OP_IDX
)
2084 if (format
& M6811_OP_IX
&& operands
[i
].reg1
== REG_X
)
2086 if (format
& M6811_OP_IY
&& operands
[i
].reg1
== REG_Y
)
2089 && format
& (M6812_OP_IDX
| M6812_OP_IDX_1
| M6812_OP_IDX_2
)
2090 && (operands
[i
].reg1
== REG_X
2091 || operands
[i
].reg1
== REG_Y
2092 || operands
[i
].reg1
== REG_SP
2093 || operands
[i
].reg1
== REG_PC
))
2095 if (i
== 1 && format
& M6812_OP_IDX_P2
)
2098 if (mode
& M6812_AUTO_INC_DEC
)
2101 && format
& (M6812_OP_IDX
| M6812_OP_IDX_1
|
2104 if (i
== 1 && format
& M6812_OP_IDX_P2
)
2109 match
= i
== nb_operands
;
2111 /* Operands are ok but an operand uses page 0 addressing mode
2112 while the insn supports abs-16 mode. Keep a reference to this
2113 insns in case there is no insn supporting page 0 addressing. */
2114 if (match
&& poss_indirect
)
2116 op_indirect
= opcode
;
2123 /* Page 0 addressing is used but not supported by any insn.
2124 If absolute addresses are supported, we use that insn. */
2125 if (match
== 0 && op_indirect
)
2127 opcode
= op_indirect
;
2139 /* Find the real opcode and its associated operands. We use a progressive
2140 approach here. On entry, 'opc' points to the first opcode in the
2141 table that matches the opcode name in the source line. We try to
2142 isolate an operand, find a possible match in the opcode table.
2143 We isolate another operand if no match were found. The table 'operands'
2144 is filled while operands are recognized.
2146 Returns the opcode pointer that matches the opcode name in the
2147 source line and the associated operands. */
2148 static struct m68hc11_opcode
*
2149 find_opcode (opc
, operands
, nb_operands
)
2150 struct m68hc11_opcode_def
*opc
;
2154 struct m68hc11_opcode
*opcode
;
2157 if (opc
->max_operands
== 0)
2163 for (i
= 0; i
< opc
->max_operands
;)
2167 result
= get_operand (&operands
[i
], i
, opc
->format
);
2171 /* Special case where the bitmask of the bclr/brclr
2172 instructions is not introduced by #.
2173 Example: bclr 3,x $80. */
2174 if (i
== 1 && (opc
->format
& M6811_OP_BITMASK
)
2175 && (operands
[i
].mode
& M6811_OP_IND16
))
2177 operands
[i
].mode
= M6811_OP_IMM16
;
2182 if (i
>= opc
->min_operands
)
2184 opcode
= find (opc
, operands
, i
);
2189 if (*input_line_pointer
== ',')
2190 input_line_pointer
++;
2196 #define M6812_XBCC_MARKER (M6812_OP_TBCC_MARKER \
2197 | M6812_OP_DBCC_MARKER \
2198 | M6812_OP_IBCC_MARKER)
2200 /* Gas line assembler entry point. */
2202 /* This is the main entry point for the machine-dependent assembler. str
2203 points to a machine-dependent instruction. This function is supposed to
2204 emit the frags/bytes it assembles to. */
2209 struct m68hc11_opcode_def
*opc
;
2210 struct m68hc11_opcode
*opcode
;
2212 unsigned char *op_start
, *save
;
2213 unsigned char *op_end
;
2216 operand operands
[M6811_MAX_OPERANDS
];
2218 int branch_optimize
= 0;
2221 /* Drop leading whitespace. */
2225 /* Find the opcode end and get the opcode in 'name'. The opcode is forced
2226 lower case (the opcode table only has lower case op-codes). */
2227 for (op_start
= op_end
= (unsigned char *) (str
);
2228 *op_end
&& nlen
< 20 && !is_end_of_line
[*op_end
] && *op_end
!= ' ';
2231 name
[nlen
] = tolower (op_start
[nlen
]);
2238 as_bad (_("No instruction or missing opcode."));
2242 /* Find the opcode definition given its name. */
2243 opc
= (struct m68hc11_opcode_def
*) hash_find (m68hc11_hash
, name
);
2245 /* If it's not recognized, look for 'jbsr' and 'jbxx'. These are
2246 pseudo insns for relative branch. For these branchs, we always
2247 optimize them (turned into absolute branchs) even if --short-branchs
2249 if (opc
== NULL
&& name
[0] == 'j' && name
[1] == 'b')
2251 opc
= (struct m68hc11_opcode_def
*) hash_find (m68hc11_hash
, &name
[1]);
2253 && (!(opc
->format
& M6811_OP_JUMP_REL
)
2254 || (opc
->format
& M6811_OP_BITMASK
)))
2257 branch_optimize
= 1;
2260 /* The following test should probably be removed. This is not conform
2261 to Motorola assembler specs. */
2262 if (opc
== NULL
&& flag_mri
)
2264 if (*op_end
== ' ' || *op_end
== '\t')
2266 while (*op_end
== ' ' || *op_end
== '\t')
2271 (is_end_of_line
[op_end
[1]]
2272 || op_end
[1] == ' ' || op_end
[1] == '\t'
2273 || !isalnum (op_end
[1])))
2274 && (*op_end
== 'a' || *op_end
== 'b'
2275 || *op_end
== 'A' || *op_end
== 'B'
2276 || *op_end
== 'd' || *op_end
== 'D'
2277 || *op_end
== 'x' || *op_end
== 'X'
2278 || *op_end
== 'y' || *op_end
== 'Y'))
2280 name
[nlen
++] = tolower (*op_end
++);
2282 opc
= (struct m68hc11_opcode_def
*) hash_find (m68hc11_hash
,
2288 /* Identify a possible instruction alias. There are some on the
2289 68HC12 to emulate a fiew 68HC11 instructions. */
2290 if (opc
== NULL
&& (current_architecture
& cpu6812
))
2294 for (i
= 0; i
< m68hc12_num_alias
; i
++)
2295 if (strcmp (m68hc12_alias
[i
].name
, name
) == 0)
2301 if (opc
== NULL
&& alias_id
< 0)
2303 as_bad (_("Opcode `%s' is not recognized."), name
);
2306 save
= input_line_pointer
;
2307 input_line_pointer
= op_end
;
2312 opcode
= find_opcode (opc
, operands
, &nb_operands
);
2317 if ((opcode
|| alias_id
>= 0) && !flag_mri
)
2319 char *p
= input_line_pointer
;
2321 while (*p
== ' ' || *p
== '\t' || *p
== '\n' || *p
== '\r')
2324 if (*p
!= '\n' && *p
)
2325 as_bad (_("Garbage at end of instruction: `%s'."), p
);
2328 input_line_pointer
= save
;
2332 char *f
= m68hc11_new_insn (m68hc12_alias
[alias_id
].size
);
2334 number_to_chars_bigendian (f
, m68hc12_alias
[alias_id
].code1
, 1);
2335 if (m68hc12_alias
[alias_id
].size
> 1)
2336 number_to_chars_bigendian (f
+ 1, m68hc12_alias
[alias_id
].code2
, 1);
2341 /* Opcode is known but does not have valid operands. Print out the
2342 syntax for this opcode. */
2345 if (flag_print_insn_syntax
)
2346 print_insn_format (name
);
2348 as_bad (_("Invalid operand for `%s'"), name
);
2352 /* Treat dbeq/ibeq/tbeq instructions in a special way. The branch is
2353 relative and must be in the range -256..255 (9-bits). */
2354 if ((opcode
->format
& M6812_XBCC_MARKER
)
2355 && (opcode
->format
& M6811_OP_JUMP_REL
))
2356 build_dbranch_insn (opcode
, operands
, nb_operands
);
2358 /* Relative jumps instructions are taken care of separately. We have to make
2359 sure that the relative branch is within the range -128..127. If it's out
2360 of range, the instructions are changed into absolute instructions.
2361 This is not supported for the brset and brclr instructions. */
2362 else if ((opcode
->format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
2363 && !(opcode
->format
& M6811_OP_BITMASK
))
2364 build_jump_insn (opcode
, operands
, nb_operands
, branch_optimize
);
2366 build_insn (opcode
, operands
, nb_operands
);
2369 /* Relocation, relaxation and frag conversions. */
2371 md_pcrel_from_section (fixp
, sec
)
2376 if (fixp
->fx_addsy
!= (symbolS
*) NULL
2377 && (!S_IS_DEFINED (fixp
->fx_addsy
)
2378 || (S_GET_SEGMENT (fixp
->fx_addsy
) != sec
)))
2381 adjust
= fixp
->fx_pcrel_adjust
;
2382 return fixp
->fx_frag
->fr_address
+ fixp
->fx_where
+ adjust
;
2385 /* If while processing a fixup, a reloc really needs to be created
2386 then it is done here. */
2388 tc_gen_reloc (section
, fixp
)
2394 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
2395 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
2396 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
2397 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
2398 if (fixp
->fx_r_type
== 0)
2399 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_16
);
2401 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
2402 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
2404 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2405 _("Relocation %d is not supported by object file format."),
2406 (int) fixp
->fx_r_type
);
2410 if (!fixp
->fx_pcrel
)
2411 reloc
->addend
= fixp
->fx_addnumber
;
2413 reloc
->addend
= (section
->vma
2414 + (fixp
->fx_pcrel_adjust
== 64
2415 ? -1 : fixp
->fx_pcrel_adjust
)
2416 + fixp
->fx_addnumber
2417 + md_pcrel_from_section (fixp
, section
));
2422 md_convert_frag (abfd
, sec
, fragP
)
2423 bfd
*abfd ATTRIBUTE_UNUSED
;
2424 asection
*sec ATTRIBUTE_UNUSED
;
2429 char *buffer_address
= fragP
->fr_literal
;
2431 /* Address in object code of the displacement. */
2432 register int object_address
= fragP
->fr_fix
+ fragP
->fr_address
;
2434 buffer_address
+= fragP
->fr_fix
;
2436 /* The displacement of the address, from current location. */
2437 disp
= fragP
->fr_symbol
? S_GET_VALUE (fragP
->fr_symbol
) : 0;
2438 disp
= (disp
+ fragP
->fr_offset
) - object_address
;
2439 disp
+= symbol_get_frag (fragP
->fr_symbol
)->fr_address
;
2441 switch (fragP
->fr_subtype
)
2443 case ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_BYTE
):
2444 fragP
->fr_opcode
[1] = disp
;
2447 case ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_WORD
):
2448 /* This relax is only for bsr and bra. */
2449 assert (IS_OPCODE (fragP
->fr_opcode
[0], M6811_BSR
)
2450 || IS_OPCODE (fragP
->fr_opcode
[0], M6811_BRA
)
2451 || IS_OPCODE (fragP
->fr_opcode
[0], M6812_BSR
));
2453 fragP
->fr_opcode
[0] = convert_branch (fragP
->fr_opcode
[0]);
2455 fix_new (fragP
, fragP
->fr_fix
- 1, 2,
2456 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_16
);
2460 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
, STATE_BYTE
):
2461 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
, STATE_BYTE
):
2462 fragP
->fr_opcode
[1] = disp
;
2465 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
, STATE_WORD
):
2466 /* Invert branch. */
2467 fragP
->fr_opcode
[0] ^= 1;
2468 fragP
->fr_opcode
[1] = 3; /* Branch offset. */
2469 buffer_address
[0] = M6811_JMP
;
2470 fix_new (fragP
, fragP
->fr_fix
+ 1, 2,
2471 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_16
);
2475 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
, STATE_WORD
):
2476 /* Translate branch into a long branch. */
2477 fragP
->fr_opcode
[1] = fragP
->fr_opcode
[0];
2478 fragP
->fr_opcode
[0] = M6811_OPCODE_PAGE2
;
2480 fixp
= fix_new (fragP
, fragP
->fr_fix
, 2,
2481 fragP
->fr_symbol
, fragP
->fr_offset
, 1,
2482 BFD_RELOC_16_PCREL
);
2483 fixp
->fx_pcrel_adjust
= 2;
2487 case ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS5
):
2488 fragP
->fr_opcode
[0] = fragP
->fr_opcode
[0] << 5;
2489 fragP
->fr_opcode
[0] |= disp
& 0x1f;
2492 case ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS9
):
2493 fragP
->fr_opcode
[0] = (fragP
->fr_opcode
[0] << 3);
2494 fragP
->fr_opcode
[0] |= 0xE0;
2495 fix_new (fragP
, fragP
->fr_fix
+ 1, 1,
2496 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_8
);
2500 case ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS16
):
2501 fragP
->fr_opcode
[0] = (fragP
->fr_opcode
[0] << 3);
2502 fragP
->fr_opcode
[0] |= 0xE2;
2503 fix_new (fragP
, fragP
->fr_fix
, 2,
2504 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_16
);
2508 case ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_BYTE
):
2510 fragP
->fr_opcode
[0] |= 0x10;
2512 fragP
->fr_opcode
[1] = disp
& 0x0FF;
2515 case ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_WORD
):
2516 /* Invert branch. */
2517 fragP
->fr_opcode
[0] ^= 0x20;
2518 fragP
->fr_opcode
[1] = 3; /* Branch offset. */
2519 buffer_address
[0] = M6812_JMP
;
2520 fix_new (fragP
, fragP
->fr_fix
+ 1, 2,
2521 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_16
);
2530 /* Force truly undefined symbols to their maximum size, and generally set up
2531 the frag list to be relaxed. */
2533 md_estimate_size_before_relax (fragP
, segment
)
2538 char *buffer_address
= fragP
->fr_fix
+ fragP
->fr_literal
;
2540 old_fr_fix
= fragP
->fr_fix
;
2542 switch (fragP
->fr_subtype
)
2544 case ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_UNDF
):
2546 /* This relax is only for bsr and bra. */
2547 assert (IS_OPCODE (fragP
->fr_opcode
[0], M6811_BSR
)
2548 || IS_OPCODE (fragP
->fr_opcode
[0], M6811_BRA
)
2549 || IS_OPCODE (fragP
->fr_opcode
[0], M6812_BSR
));
2551 /* A relaxable case. */
2552 if (S_GET_SEGMENT (fragP
->fr_symbol
) == segment
)
2554 fragP
->fr_subtype
= ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_BYTE
);
2558 if (flag_fixed_branchs
)
2559 as_bad_where (fragP
->fr_file
, fragP
->fr_line
,
2560 _("bra or bsr with undefined symbol."));
2562 /* The symbol is undefined or in a separate section. Turn bra into a
2563 jmp and bsr into a jsr. The insn becomes 3 bytes long (instead of
2564 2). A fixup is necessary for the unresolved symbol address. */
2566 fragP
->fr_opcode
[0] = convert_branch (fragP
->fr_opcode
[0]);
2569 fix_new (fragP
, old_fr_fix
- 1, 2, fragP
->fr_symbol
,
2570 fragP
->fr_offset
, 0, BFD_RELOC_16
);
2575 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
, STATE_UNDF
):
2576 assert (current_architecture
& cpu6811
);
2578 if (S_GET_SEGMENT (fragP
->fr_symbol
) == segment
)
2580 fragP
->fr_subtype
= ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
,
2585 fragP
->fr_opcode
[0] ^= 1; /* Reverse sense of branch. */
2586 fragP
->fr_opcode
[1] = 3; /* Skip next jmp insn (3 bytes). */
2588 /* Don't use fr_opcode[2] because this may be
2589 in a different frag. */
2590 buffer_address
[0] = M6811_JMP
;
2593 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
2594 fragP
->fr_offset
, 0, BFD_RELOC_16
);
2600 case ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_UNDF
):
2601 assert (current_architecture
& cpu6812
);
2603 if (S_GET_SEGMENT (fragP
->fr_symbol
) == segment
)
2605 fragP
->fr_subtype
= ENCODE_RELAX (STATE_INDEXED_OFFSET
,
2610 /* Switch the indexed operation to 16-bit mode. */
2611 if ((fragP
->fr_opcode
[1] & 0x21) == 0x20)
2612 fragP
->fr_opcode
[1] = (fragP
->fr_opcode
[1] >> 3) | 0xc0 | 0x02;
2615 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
2616 fragP
->fr_offset
, 0, BFD_RELOC_16
);
2622 case ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_UNDF
):
2623 assert (current_architecture
& cpu6812
);
2625 if (S_GET_SEGMENT (fragP
->fr_symbol
) == segment
)
2627 fragP
->fr_subtype
= ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_BYTE
);
2631 fragP
->fr_opcode
[0] ^= 0x20; /* Reverse sense of branch. */
2632 fragP
->fr_opcode
[1] = 3; /* Skip next jmp insn (3 bytes). */
2634 /* Don't use fr_opcode[2] because this may be
2635 in a different frag. */
2636 buffer_address
[0] = M6812_JMP
;
2639 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
2640 fragP
->fr_offset
, 0, BFD_RELOC_16
);
2646 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
, STATE_UNDF
):
2647 assert (current_architecture
& cpu6812
);
2649 if (S_GET_SEGMENT (fragP
->fr_symbol
) == segment
)
2651 fragP
->fr_subtype
= ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
,
2656 /* Translate into a lbcc branch. */
2657 fragP
->fr_opcode
[1] = fragP
->fr_opcode
[0];
2658 fragP
->fr_opcode
[0] = M6811_OPCODE_PAGE2
;
2660 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
2661 fragP
->fr_offset
, 0, BFD_RELOC_16_PCREL
);
2668 as_fatal (_("Subtype %d is not recognized."), fragP
->fr_subtype
);
2671 return (fragP
->fr_fix
- old_fr_fix
);
2675 md_apply_fix (fixp
, valuep
)
2683 if (fixp
->fx_addsy
== (symbolS
*) NULL
)
2688 else if (fixp
->fx_pcrel
)
2694 value
= fixp
->fx_offset
;
2695 if (fixp
->fx_subsy
!= (symbolS
*) NULL
)
2697 if (S_GET_SEGMENT (fixp
->fx_subsy
) == absolute_section
)
2699 value
-= S_GET_VALUE (fixp
->fx_subsy
);
2703 /* We don't actually support subtracting a symbol. */
2704 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2705 _("Expression too complex."));
2710 op_type
= fixp
->fx_r_type
;
2712 /* Patch the instruction with the resolved operand. Elf relocation
2713 info will also be generated to take care of linker/loader fixups.
2714 The 68HC11 addresses only 64Kb, we are only concerned by 8 and 16-bit
2715 relocs. BFD_RELOC_8 is basically used for .page0 access (the linker
2716 will warn for overflows). BFD_RELOC_8_PCREL should not be generated
2717 because it's either resolved or turned out into non-relative insns (see
2718 relax table, bcc, bra, bsr transformations)
2720 The BFD_RELOC_32 is necessary for the support of --gstabs. */
2721 where
= fixp
->fx_frag
->fr_literal
+ fixp
->fx_where
;
2723 switch (fixp
->fx_r_type
)
2726 bfd_putb32 ((bfd_vma
) value
, (unsigned char *) where
);
2730 case BFD_RELOC_16_PCREL
:
2731 bfd_putb16 ((bfd_vma
) value
, (unsigned char *) where
);
2732 if (value
< -65537 || value
> 65535)
2733 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2734 _("Value out of 16-bit range."));
2737 case BFD_RELOC_M68HC11_HI8
:
2741 case BFD_RELOC_M68HC11_LO8
:
2744 bfd_putb8 ((bfd_vma
) value
, (unsigned char *) where
);
2746 ((bfd_byte
*) where
)[0] = (bfd_byte
) value
;
2749 case BFD_RELOC_8_PCREL
:
2751 bfd_putb8 ((bfd_vma
) value
, (unsigned char *) where
);
2753 ((bfd_byte
*) where
)[0] = (bfd_byte
) value
;
2755 if (value
< -128 || value
> 127)
2756 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2757 _("Value %ld too large for 8-bit PC-relative branch."),
2761 case BFD_RELOC_M68HC11_3B
:
2762 if (value
<= 0 || value
> 8)
2763 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2764 _("Auto increment/decrement offset '%ld' is out of range."),
2771 where
[0] = where
[0] | (value
& 0x07);
2775 as_fatal (_("Line %d: unknown relocation type: 0x%x."),
2776 fixp
->fx_line
, fixp
->fx_r_type
);