1 /* tc-m68hc11.c -- Assembler code for the Motorola 68HC11 & 68HC12.
2 Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010,
4 Free Software Foundation, Inc.
5 Written by Stephane Carrez (stcarrez@nerim.fr)
6 XGATE and S12X added by James Murray (jsm@jsm-net.demon.co.uk)
8 This file is part of GAS, the GNU Assembler.
10 GAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3, or (at your option)
15 GAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with GAS; see the file COPYING. If not, write to
22 the Free Software Foundation, 51 Franklin Street - Fifth Floor,
23 Boston, MA 02110-1301, USA. */
26 #include "safe-ctype.h"
28 #include "opcode/m68hc11.h"
29 #include "dwarf2dbg.h"
30 #include "elf/m68hc11.h"
32 const char comment_chars
[] = ";!";
33 const char line_comment_chars
[] = "#*";
34 const char line_separator_chars
[] = "";
36 const char EXP_CHARS
[] = "eE";
37 const char FLT_CHARS
[] = "dD";
39 #define STATE_CONDITIONAL_BRANCH (1)
40 #define STATE_PC_RELATIVE (2)
41 #define STATE_INDEXED_OFFSET (3)
42 #define STATE_INDEXED_PCREL (4)
43 #define STATE_XBCC_BRANCH (5)
44 #define STATE_CONDITIONAL_BRANCH_6812 (6)
46 #define STATE_BYTE (0)
47 #define STATE_BITS5 (0)
48 #define STATE_WORD (1)
49 #define STATE_BITS9 (1)
50 #define STATE_LONG (2)
51 #define STATE_BITS16 (2)
52 #define STATE_UNDF (3) /* Symbol undefined in pass1 */
54 /* This macro has no side-effects. */
55 #define ENCODE_RELAX(what,length) (((what) << 2) + (length))
56 #define RELAX_STATE(s) ((s) >> 2)
57 #define RELAX_LENGTH(s) ((s) & 3)
59 #define IS_OPCODE(C1,C2) (((C1) & 0x0FF) == ((C2) & 0x0FF))
61 /* This table describes how you change sizes for the various types of variable
62 size expressions. This version only supports two kinds. */
65 How far Forward this mode will reach.
66 How far Backward this mode will reach.
67 How many bytes this mode will add to the size of the frag.
68 Which mode to go to if the offset won't fit in this one. */
70 relax_typeS md_relax_table
[] =
72 {1, 1, 0, 0}, /* First entries aren't used. */
73 {1, 1, 0, 0}, /* For no good reason except. */
74 {1, 1, 0, 0}, /* that the VAX doesn't either. */
78 These insns are translated into b!cc +3 jmp L. */
79 {(127), (-128), 0, ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
, STATE_WORD
)},
84 /* Relax for bsr <L> and bra <L>.
85 These insns are translated into jsr and jmp. */
86 {(127), (-128), 0, ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_WORD
)},
91 /* Relax for indexed offset: 5-bits, 9-bits, 16-bits. */
92 {(15), (-16), 0, ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS9
)},
93 {(255), (-256), 1, ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS16
)},
97 /* Relax for PC relative offset: 5-bits, 9-bits, 16-bits.
98 For the 9-bit case, there will be a -1 correction to take into
99 account the new byte that's why the range is -255..256. */
100 {(15), (-16), 0, ENCODE_RELAX (STATE_INDEXED_PCREL
, STATE_BITS9
)},
101 {(256), (-255), 1, ENCODE_RELAX (STATE_INDEXED_PCREL
, STATE_BITS16
)},
105 /* Relax for dbeq/ibeq/tbeq r,<L>:
106 These insns are translated into db!cc +3 jmp L. */
107 {(255), (-256), 0, ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_WORD
)},
112 /* Relax for bcc <L> on 68HC12.
113 These insns are translated into lbcc <L>. */
114 {(127), (-128), 0, ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
, STATE_WORD
)},
121 /* 68HC11 and 68HC12 registers. They are numbered according to the 68HC12. */
122 typedef enum register_id
146 typedef struct operand
154 struct m68hc11_opcode_def
161 struct m68hc11_opcode
*opcode
;
164 static struct m68hc11_opcode_def
*m68hc11_opcode_defs
= 0;
165 static int m68hc11_nb_opcode_defs
= 0;
173 static alias alias_opcodes
[] =
181 struct m9s12xg_opcode_def
188 struct m9s12xg_opcode
*opcode
;
191 /* Local functions. */
192 static register_id
reg_name_search (char *);
193 static register_id
register_name (void);
194 static int cmp_opcode (struct m68hc11_opcode
*, struct m68hc11_opcode
*);
195 static char *print_opcode_format (struct m68hc11_opcode
*, int);
196 static char *skip_whites (char *);
197 static int check_range (long, int);
198 static void print_opcode_list (void);
199 static void get_default_target (void);
200 static void print_insn_format (char *);
201 static int get_operand (operand
*, int, long);
202 static void fixup8 (expressionS
*, int, int);
203 static void fixup16 (expressionS
*, int, int);
204 static void fixup24 (expressionS
*, int, int);
205 static void fixup8_xg (expressionS
*, int, int);
206 static unsigned char convert_branch (unsigned char);
207 static char *m68hc11_new_insn (int);
208 static void build_dbranch_insn (struct m68hc11_opcode
*,
209 operand
*, int, int);
210 static int build_indexed_byte (operand
*, int, int);
211 static int build_reg_mode (operand
*, int);
213 static struct m68hc11_opcode
*find (struct m68hc11_opcode_def
*,
215 static struct m68hc11_opcode
*find_opcode (struct m68hc11_opcode_def
*,
217 static void build_jump_insn (struct m68hc11_opcode
*, operand
*, int, int);
218 static void build_insn_xg (struct m68hc11_opcode
*, operand
*, int);
219 static void build_insn (struct m68hc11_opcode
*, operand
*, int);
220 static int relaxable_symbol (symbolS
*);
222 /* Pseudo op to indicate a relax group. */
223 static void s_m68hc11_relax (int);
225 /* Pseudo op to control the ELF flags. */
226 static void s_m68hc11_mode (int);
228 /* Mark the symbols with STO_M68HC12_FAR to indicate the functions
229 are using 'rtc' for returning. It is necessary to use 'call'
230 to invoke them. This is also used by the debugger to correctly
231 find the stack frame. */
232 static void s_m68hc11_mark_symbol (int);
234 /* Controls whether relative branches can be turned into long branches.
235 When the relative offset is too large, the insn are changed:
243 Setting the flag forbidds this. */
244 static short flag_fixed_branches
= 0;
246 /* Force to use long jumps (absolute) instead of relative branches. */
247 static short flag_force_long_jumps
= 0;
249 /* Change the direct addressing mode into an absolute addressing mode
250 when the insn does not support direct addressing.
251 For example, "clr *ZD0" is normally not possible and is changed
253 static short flag_strict_direct_addressing
= 1;
255 /* When an opcode has invalid operand, print out the syntax of the opcode
257 static short flag_print_insn_syntax
= 0;
259 /* Dumps the list of instructions with syntax and then exit:
260 1 -> Only dumps the list (sorted by name)
261 2 -> Generate an example (or test) that can be compiled. */
262 static short flag_print_opcodes
= 0;
264 /* Opcode hash table. */
265 static struct hash_control
*m68hc11_hash
;
267 /* Current cpu (either cpu6811 or cpu6812). This is determined automagically
268 by 'get_default_target' by looking at default BFD vector. This is overridden
269 with the -m<cpu> option. */
270 static int current_architecture
= 0;
272 /* Default cpu determined by 'get_default_target'. */
273 static const char *default_cpu
;
275 /* Number of opcodes in the sorted table (filtered by current cpu). */
276 static int num_opcodes
;
278 /* The opcodes sorted by name and filtered by current cpu. */
279 static struct m68hc11_opcode
*m68hc11_sorted_opcodes
;
281 /* ELF flags to set in the output file header. */
282 static int elf_flags
= E_M68HC11_F64
;
284 /* These are the machine dependent pseudo-ops. These are included so
285 the assembler can work on the output from the SUN C compiler, which
288 /* This table describes all the machine specific pseudo-ops the assembler
289 has to support. The fields are:
290 pseudo-op name without dot
291 function to call to execute this pseudo-op
292 Integer arg to pass to the function. */
293 const pseudo_typeS md_pseudo_table
[] =
295 /* The following pseudo-ops are supported for MRI compatibility. */
299 {"fcc", stringer
, 8 + 1},
303 {"xrefb", s_ignore
, 0}, /* Same as xref */
305 /* Gcc driven relaxation. */
306 {"relax", s_m68hc11_relax
, 0},
308 /* .mode instruction (ala SH). */
309 {"mode", s_m68hc11_mode
, 0},
311 /* .far instruction. */
312 {"far", s_m68hc11_mark_symbol
, STO_M68HC12_FAR
},
314 /* .interrupt instruction. */
315 {"interrupt", s_m68hc11_mark_symbol
, STO_M68HC12_INTERRUPT
},
320 /* Options and initialization. */
322 const char *md_shortopts
= "Sm:";
324 struct option md_longopts
[] =
326 #define OPTION_FORCE_LONG_BRANCH (OPTION_MD_BASE)
327 {"force-long-branches", no_argument
, NULL
, OPTION_FORCE_LONG_BRANCH
},
328 {"force-long-branchs", no_argument
, NULL
, OPTION_FORCE_LONG_BRANCH
}, /* Misspelt version kept for backwards compatibility. */
330 #define OPTION_SHORT_BRANCHES (OPTION_MD_BASE + 1)
331 {"short-branches", no_argument
, NULL
, OPTION_SHORT_BRANCHES
},
332 {"short-branchs", no_argument
, NULL
, OPTION_SHORT_BRANCHES
}, /* Misspelt version kept for backwards compatibility. */
334 #define OPTION_STRICT_DIRECT_MODE (OPTION_MD_BASE + 2)
335 {"strict-direct-mode", no_argument
, NULL
, OPTION_STRICT_DIRECT_MODE
},
337 #define OPTION_PRINT_INSN_SYNTAX (OPTION_MD_BASE + 3)
338 {"print-insn-syntax", no_argument
, NULL
, OPTION_PRINT_INSN_SYNTAX
},
340 #define OPTION_PRINT_OPCODES (OPTION_MD_BASE + 4)
341 {"print-opcodes", no_argument
, NULL
, OPTION_PRINT_OPCODES
},
343 #define OPTION_GENERATE_EXAMPLE (OPTION_MD_BASE + 5)
344 {"generate-example", no_argument
, NULL
, OPTION_GENERATE_EXAMPLE
},
346 #define OPTION_MSHORT (OPTION_MD_BASE + 6)
347 {"mshort", no_argument
, NULL
, OPTION_MSHORT
},
349 #define OPTION_MLONG (OPTION_MD_BASE + 7)
350 {"mlong", no_argument
, NULL
, OPTION_MLONG
},
352 #define OPTION_MSHORT_DOUBLE (OPTION_MD_BASE + 8)
353 {"mshort-double", no_argument
, NULL
, OPTION_MSHORT_DOUBLE
},
355 #define OPTION_MLONG_DOUBLE (OPTION_MD_BASE + 9)
356 {"mlong-double", no_argument
, NULL
, OPTION_MLONG_DOUBLE
},
358 #define OPTION_XGATE_RAMOFFSET (OPTION_MD_BASE + 10)
359 {"xgate-ramoffset", no_argument
, NULL
, OPTION_XGATE_RAMOFFSET
},
361 {NULL
, no_argument
, NULL
, 0}
363 size_t md_longopts_size
= sizeof (md_longopts
);
365 /* Get the target cpu for the assembler. This is based on the configure
366 options and on the -m68hc11/-m68hc12 option. If no option is specified,
367 we must get the default. */
369 m68hc11_arch_format (void)
371 get_default_target ();
372 if (current_architecture
& cpu6811
)
373 return "elf32-m68hc11";
375 return "elf32-m68hc12";
378 enum bfd_architecture
381 get_default_target ();
382 if (current_architecture
& cpu6811
)
383 return bfd_arch_m68hc11
;
385 return bfd_arch_m68hc12
;
394 /* Listing header selected according to cpu. */
396 m68hc11_listing_header (void)
398 if (current_architecture
& cpu6811
)
399 return "M68HC11 GAS ";
400 else if (current_architecture
& cpuxgate
)
402 else if (current_architecture
& cpu9s12x
)
405 return "M68HC12 GAS ";
409 md_show_usage (FILE *stream
)
411 get_default_target ();
412 fprintf (stream
, _("\
413 Motorola 68HC11/68HC12/68HCS12 options:\n\
414 -m68hc11 | -m68hc12 |\n\
415 -m68hcs12 | -mm9s12x |\n\
416 -mm9s12xg specify the processor [default %s]\n\
417 -mshort use 16-bit int ABI (default)\n\
418 -mlong use 32-bit int ABI\n\
419 -mshort-double use 32-bit double ABI\n\
420 -mlong-double use 64-bit double ABI (default)\n\
421 --force-long-branches always turn relative branches into absolute ones\n\
422 -S,--short-branches do not turn relative branches into absolute ones\n\
423 when the offset is out of range\n\
424 --strict-direct-mode do not turn the direct mode into extended mode\n\
425 when the instruction does not support direct mode\n\
426 --print-insn-syntax print the syntax of instruction in case of error\n\
427 --print-opcodes print the list of instructions with syntax\n\
428 --xgate-ramoffset offset ram addresses by 0xc000\n\
429 --generate-example generate an example of each instruction\n\
430 (used for testing)\n"), default_cpu
);
434 /* Try to identify the default target based on the BFD library. */
436 get_default_target (void)
438 const bfd_target
*target
;
441 if (current_architecture
!= 0)
444 default_cpu
= "unknown";
445 target
= bfd_find_target (0, &abfd
);
446 if (target
&& target
->name
)
448 if (strcmp (target
->name
, "elf32-m68hc12") == 0)
450 current_architecture
= cpu6812
;
451 default_cpu
= "m68hc12";
453 else if (strcmp (target
->name
, "elf32-m68hc11") == 0)
455 current_architecture
= cpu6811
;
456 default_cpu
= "m68hc11";
460 as_bad (_("Default target `%s' is not supported."), target
->name
);
466 m68hc11_print_statistics (FILE *file
)
469 struct m68hc11_opcode_def
*opc
;
471 hash_print_statistics (file
, "opcode table", m68hc11_hash
);
473 opc
= m68hc11_opcode_defs
;
474 if (opc
== 0 || m68hc11_nb_opcode_defs
== 0)
477 /* Dump the opcode statistics table. */
478 fprintf (file
, _("Name # Modes Min ops Max ops Modes mask # Used\n"));
479 for (i
= 0; i
< m68hc11_nb_opcode_defs
; i
++, opc
++)
481 fprintf (file
, "%-7.7s %5d %7d %7d 0x%08lx %7d\n",
484 opc
->min_operands
, opc
->max_operands
, opc
->format
, opc
->used
);
489 md_parse_option (int c
, char *arg
)
491 get_default_target ();
494 /* -S means keep external to 2 bit offset rather than 16 bit one. */
495 case OPTION_SHORT_BRANCHES
:
497 flag_fixed_branches
= 1;
500 case OPTION_FORCE_LONG_BRANCH
:
501 flag_force_long_jumps
= 1;
504 case OPTION_PRINT_INSN_SYNTAX
:
505 flag_print_insn_syntax
= 1;
508 case OPTION_PRINT_OPCODES
:
509 flag_print_opcodes
= 1;
512 case OPTION_STRICT_DIRECT_MODE
:
513 flag_strict_direct_addressing
= 0;
516 case OPTION_GENERATE_EXAMPLE
:
517 flag_print_opcodes
= 2;
521 elf_flags
&= ~E_M68HC11_I32
;
525 elf_flags
|= E_M68HC11_I32
;
528 case OPTION_MSHORT_DOUBLE
:
529 elf_flags
&= ~E_M68HC11_F64
;
532 case OPTION_MLONG_DOUBLE
:
533 elf_flags
|= E_M68HC11_F64
;
536 case OPTION_XGATE_RAMOFFSET
:
537 elf_flags
|= E_M68HC11_XGATE_RAMOFFSET
;
541 if ((strcasecmp (arg
, "68hc11") == 0)
542 || (strcasecmp (arg
, "m68hc11") == 0))
543 current_architecture
= cpu6811
;
544 else if ((strcasecmp (arg
, "68hc12") == 0)
545 || (strcasecmp (arg
, "m68hc12") == 0))
546 current_architecture
= cpu6812
;
547 else if ((strcasecmp (arg
, "68hcs12") == 0)
548 || (strcasecmp (arg
, "m68hcs12") == 0))
549 current_architecture
= cpu6812
| cpu6812s
;
550 else if (strcasecmp (arg
, "m9s12x") == 0)
551 current_architecture
= cpu6812
| cpu6812s
| cpu9s12x
;
552 else if ((strcasecmp (arg
, "m9s12xg") == 0)
553 || (strcasecmp (arg
, "xgate") == 0))
554 /* xgate for backwards compatability */
555 current_architecture
= cpuxgate
;
557 as_bad (_("Option `%s' is not recognized."), arg
);
568 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
574 md_atof (int type
, char *litP
, int *sizeP
)
576 return ieee_md_atof (type
, litP
, sizeP
, TRUE
);
580 md_section_align (asection
*seg
, valueT addr
)
582 int align
= bfd_get_section_alignment (stdoutput
, seg
);
583 return ((addr
+ (1 << align
) - 1) & (-1 << align
));
587 cmp_opcode (struct m68hc11_opcode
*op1
, struct m68hc11_opcode
*op2
)
589 return strcmp (op1
->name
, op2
->name
);
592 #define IS_CALL_SYMBOL(MODE) \
593 (((MODE) & (M6812_OP_PAGE|M6811_OP_IND16)) \
594 == ((M6812_OP_PAGE|M6811_OP_IND16)))
596 /* Initialize the assembler. Create the opcode hash table
597 (sorted on the names) with the M6811 opcode table
598 (from opcode library). */
602 char *prev_name
= "";
603 struct m68hc11_opcode
*opcodes
;
604 struct m68hc11_opcode_def
*opc
= 0;
607 get_default_target ();
609 m68hc11_hash
= hash_new ();
611 /* Get a writable copy of the opcode table and sort it on the names. */
612 opcodes
= (struct m68hc11_opcode
*) xmalloc (m68hc11_num_opcodes
*
615 m68hc11_sorted_opcodes
= opcodes
;
617 for (i
= 0; i
< m68hc11_num_opcodes
; i
++)
619 if (m68hc11_opcodes
[i
].arch
& current_architecture
)
621 opcodes
[num_opcodes
] = m68hc11_opcodes
[i
];
622 if (opcodes
[num_opcodes
].name
[0] == 'b'
623 && opcodes
[num_opcodes
].format
& M6811_OP_JUMP_REL
624 && !(opcodes
[num_opcodes
].format
& M6811_OP_BITMASK
))
627 opcodes
[num_opcodes
] = m68hc11_opcodes
[i
];
630 for (j
= 0; alias_opcodes
[j
].name
!= 0; j
++)
631 if (strcmp (m68hc11_opcodes
[i
].name
, alias_opcodes
[j
].name
) == 0)
633 opcodes
[num_opcodes
] = m68hc11_opcodes
[i
];
634 opcodes
[num_opcodes
].name
= alias_opcodes
[j
].alias
;
640 qsort (opcodes
, num_opcodes
, sizeof (struct m68hc11_opcode
),
641 (int (*) (const void*, const void*)) cmp_opcode
);
643 opc
= (struct m68hc11_opcode_def
*)
644 xmalloc (num_opcodes
* sizeof (struct m68hc11_opcode_def
));
645 m68hc11_opcode_defs
= opc
--;
647 /* Insert unique names into hash table. The M6811 instruction set
648 has several identical opcode names that have different opcodes based
649 on the operands. This hash table then provides a quick index to
650 the first opcode with a particular name in the opcode table. */
651 for (i
= 0; i
< num_opcodes
; i
++, opcodes
++)
655 if (strcmp (prev_name
, opcodes
->name
))
657 prev_name
= (char *) opcodes
->name
;
661 opc
->min_operands
= 100;
662 opc
->max_operands
= 0;
664 opc
->opcode
= opcodes
;
666 hash_insert (m68hc11_hash
, opcodes
->name
, opc
);
669 opc
->format
|= opcodes
->format
;
671 /* See how many operands this opcode needs. */
673 if (opcodes
->arch
== cpuxgate
)
675 if (opcodes
->format
& (M68XG_OP_IMM3
| M68XG_OP_R
| M68XG_OP_REL9
678 else if (opcodes
->format
& (M68XG_OP_R_R
| M68XG_OP_R_IMM4
679 | M68XG_OP_R_IMM8
| M68XG_OP_R_IMM8
))
681 else if (opcodes
->format
& (M68XG_OP_R_R_R
| M68XG_OP_R_R_OFFS5
682 | M68XG_OP_RD_RB_RI
| M68XG_OP_RD_RB_RIp
683 | M68XG_OP_RD_RB_mRI
))
688 if (opcodes
->format
& M6811_OP_MASK
)
690 if (opcodes
->format
& M6811_OP_BITMASK
)
692 if (opcodes
->format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
694 if (opcodes
->format
& (M6812_OP_IND16_P2
| M6812_OP_IDX_P2
))
696 /* Special case for call instruction. */
697 if ((opcodes
->format
& M6812_OP_PAGE
)
698 && !(opcodes
->format
& M6811_OP_IND16
))
702 if (expect
< opc
->min_operands
)
703 opc
->min_operands
= expect
;
704 if (IS_CALL_SYMBOL (opcodes
->format
))
706 if (expect
> opc
->max_operands
)
707 opc
->max_operands
= expect
;
710 m68hc11_nb_opcode_defs
= opc
- m68hc11_opcode_defs
;
712 if (flag_print_opcodes
)
714 print_opcode_list ();
720 m68hc11_init_after_args (void)
726 /* Return a string that represents the operand format for the instruction.
727 When example is true, this generates an example of operand. This is used
728 to give an example and also to generate a test. */
731 print_opcode_format (struct m68hc11_opcode
*opcode
, int example
)
733 static char buf
[128];
734 int format
= opcode
->format
;
740 if (current_architecture
== cpuxgate
)
742 if (format
& M68XG_OP_IMM3
)
745 sprintf (p
, "#%d", rand () & 0x007);
747 strcpy (p
, _("imm3"));
750 else if (format
& M68XG_OP_R
)
753 sprintf (p
, "R%d", rand () & 0x07);
758 else if (format
& M68XG_OP_R_R
)
761 sprintf (p
, "R%d,R%d", rand () & 0x07, rand () & 0x07);
763 strcpy (p
, _("RD,RS"));
766 else if (format
& M68XG_OP_R_IMM4
)
769 sprintf (p
, "R%d,#%d", rand () & 0x07, rand () & 0x0f);
771 strcpy (p
, _("RI, #imm4"));
774 else if (format
& M68XG_OP_R_R_R
)
777 sprintf (p
, "R%d,R%d,R%d", rand () & 0x07, rand () & 0x07, rand () & 0x07);
779 strcpy (p
, "RD,RS1,RS2");
782 else if (format
& M68XG_OP_REL9
)
785 sprintf (p
, "%d", rand () & 0x1FF);
787 strcpy (p
, "<rel9>");
790 else if (format
& M68XG_OP_REL10
)
793 sprintf (p
, "%d", rand () & 0x3FF);
795 strcpy (p
, "<rel10>");
798 else if (format
& M68XG_OP_R_R_OFFS5
)
801 sprintf (p
, "R%d, (R%d, #0x%x)", rand () & 0x07, rand () & 0x07, rand () & 0x1f);
803 strcpy (p
, _("RD, (RI,#offs5)"));
806 else if (format
& M68XG_OP_RD_RB_RI
)
809 sprintf (p
, "R%d, (R%d, R%d)", rand () & 0x07, rand () & 0x07, rand () & 0x07);
811 strcpy (p
, "RD, (RB, RI)");
814 else if (format
& M68XG_OP_RD_RB_RIp
)
817 sprintf (p
, "R%d, (R%d, R%d+)", rand () & 0x07, rand () & 0x07, rand () & 0x07);
819 strcpy (p
, "RD, (RB, RI+)");
822 else if (format
& M68XG_OP_RD_RB_mRI
)
825 sprintf (p
, "R%d, (R%d, -R%d)", rand () & 0x07, rand () & 0x07, rand () & 0x07);
827 strcpy (p
, "RD, (RB, -RI)");
830 else if (format
& M68XG_OP_R_IMM8
)
833 sprintf (p
, "R%d, #0x%x", rand () & 0x07, rand () & 0xff);
835 strcpy (p
, "RD, #imm8");
838 else if (format
& M68XG_OP_R_IMM16
)
841 sprintf (p
, "R%d, #0x%x", rand () & 0x07, rand () & 0xffff);
843 strcpy (p
, "RD, #imm16");
850 if (format
& M6811_OP_IMM8
)
853 sprintf (p
, "#%d", rand () & 0x0FF);
855 strcpy (p
, _("#<imm8>"));
859 if (format
& M6811_OP_IMM16
)
862 sprintf (p
, "#%d", rand () & 0x0FFFF);
864 strcpy (p
, _("#<imm16>"));
868 if (format
& M6811_OP_IX
)
871 sprintf (p
, "%d,X", rand () & 0x0FF);
873 strcpy (p
, _("<imm8>,X"));
877 if (format
& M6811_OP_IY
)
880 sprintf (p
, "%d,X", rand () & 0x0FF);
882 strcpy (p
, _("<imm8>,X"));
886 if (format
& M6812_OP_IDX
)
889 sprintf (p
, "%d,X", rand () & 0x0FF);
895 if (format
& M6812_OP_PAGE
)
898 sprintf (p
, ", %d", rand () & 0x0FF);
900 strcpy (p
, ", <page>");
904 if (format
& M6811_OP_DIRECT
)
907 sprintf (p
, "*Z%d", rand () & 0x0FF);
909 strcpy (p
, _("*<abs8>"));
913 if (format
& M6811_OP_BITMASK
)
919 sprintf (p
, "#$%02x", rand () & 0x0FF);
921 strcpy (p
, _("#<mask>"));
924 if (format
& M6811_OP_JUMP_REL
)
928 if (format
& M6811_OP_IND16
)
931 sprintf (p
, _("symbol%d"), rand () & 0x0FF);
933 strcpy (p
, _("<abs>"));
938 if (format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
942 if (format
& M6811_OP_BITMASK
)
944 sprintf (p
, ".+%d", rand () & 0x7F);
948 sprintf (p
, "L%d", rand () & 0x0FF);
952 strcpy (p
, _("<label>"));
958 /* Prints the list of instructions with the possible operands. */
960 print_opcode_list (void)
963 char *prev_name
= "";
964 struct m68hc11_opcode
*opcodes
;
965 int example
= flag_print_opcodes
== 2;
968 printf (_("# Example of `%s' instructions\n\t.sect .text\n_start:\n"),
971 opcodes
= m68hc11_sorted_opcodes
;
973 /* Walk the list sorted on names (by md_begin). We only report
974 one instruction per line, and we collect the different operand
976 for (i
= 0; i
< num_opcodes
; i
++, opcodes
++)
978 char *fmt
= print_opcode_format (opcodes
, example
);
982 printf ("L%d:\t", i
);
983 printf ("%s %s\n", opcodes
->name
, fmt
);
987 if (strcmp (prev_name
, opcodes
->name
))
992 printf ("%-5.5s ", opcodes
->name
);
993 prev_name
= (char *) opcodes
->name
;
996 printf (" [%s]", fmt
);
1002 /* Print the instruction format. This operation is called when some
1003 instruction is not correct. Instruction format is printed as an
1006 print_insn_format (char *name
)
1008 struct m68hc11_opcode_def
*opc
;
1009 struct m68hc11_opcode
*opcode
;
1012 opc
= (struct m68hc11_opcode_def
*) hash_find (m68hc11_hash
, name
);
1015 as_bad (_("Instruction `%s' is not recognized."), name
);
1018 opcode
= opc
->opcode
;
1020 as_bad (_("Instruction formats for `%s':"), name
);
1025 fmt
= print_opcode_format (opcode
, 0);
1026 sprintf (buf
, "\t%-5.5s %s", opcode
->name
, fmt
);
1031 while (strcmp (opcode
->name
, name
) == 0);
1034 /* Analysis of 68HC11 and 68HC12 operands. */
1036 /* reg_name_search() finds the register number given its name.
1037 Returns the register number or REG_NONE on failure. */
1039 reg_name_search (char *name
)
1041 if (strcasecmp (name
, "x") == 0 || strcasecmp (name
, "ix") == 0)
1043 if (strcasecmp (name
, "y") == 0 || strcasecmp (name
, "iy") == 0)
1045 if (strcasecmp (name
, "a") == 0)
1047 if (strcasecmp (name
, "b") == 0)
1049 if (strcasecmp (name
, "d") == 0)
1051 if (strcasecmp (name
, "sp") == 0)
1053 if (strcasecmp (name
, "pc") == 0)
1055 if (strcasecmp (name
, "ccr") == 0)
1058 if (strcasecmp (name
, "r0") == 0)
1060 if (strcasecmp (name
, "r1") == 0)
1062 if (strcasecmp (name
, "r2") == 0)
1064 if (strcasecmp (name
, "r3") == 0)
1066 if (strcasecmp (name
, "r4") == 0)
1068 if (strcasecmp (name
, "r5") == 0)
1070 if (strcasecmp (name
, "r6") == 0)
1072 if (strcasecmp (name
, "r7") == 0)
1074 if (strcasecmp (name
, "sp") == 0)
1076 if (strcasecmp (name
, "pc") == 0)
1078 if (strcasecmp (name
, "ccr") == 0)
1084 skip_whites (char *p
)
1086 while (*p
== ' ' || *p
== '\t')
1092 /* Check the string at input_line_pointer
1093 to see if it is a valid register name. */
1095 register_name (void)
1097 register_id reg_number
;
1098 char c
, *p
= input_line_pointer
;
1100 if (!is_name_beginner (*p
++))
1103 while (is_part_of_name (*p
++))
1110 /* Look to see if it's in the register table. */
1111 reg_number
= reg_name_search (input_line_pointer
);
1112 if (reg_number
!= REG_NONE
)
1117 input_line_pointer
= p
;
1125 #define M6811_OP_CALL_ADDR 0x00800000
1126 #define M6811_OP_PAGE_ADDR 0x04000000
1128 /* Parse a string of operands and return an array of expressions.
1130 Operand mode[0] mode[1] exp[0] exp[1]
1131 #n M6811_OP_IMM16 - O_*
1132 *<exp> M6811_OP_DIRECT - O_*
1133 .{+-}<exp> M6811_OP_JUMP_REL - O_*
1134 <exp> M6811_OP_IND16 - O_*
1135 ,r N,r M6812_OP_IDX M6812_OP_REG O_constant O_register
1136 n,-r M6812_PRE_DEC M6812_OP_REG O_constant O_register
1137 n,+r M6812_PRE_INC " "
1138 n,r- M6812_POST_DEC " "
1139 n,r+ M6812_POST_INC " "
1140 A,r B,r D,r M6811_OP_REG M6812_OP_REG O_register O_register
1141 [D,r] M6811_OP_D_IDX M6812_OP_REG O_register O_register
1142 [n,r] M6811_OP_D_IDX_2 M6812_OP_REG O_constant O_register */
1144 get_operand (operand
*oper
, int which
, long opmode
)
1146 char *p
= input_line_pointer
;
1150 oper
->exp
.X_op
= O_absent
;
1151 oper
->reg1
= REG_NONE
;
1152 oper
->reg2
= REG_NONE
;
1153 mode
= M6811_OP_NONE
;
1155 p
= skip_whites (p
);
1157 if (*p
== 0 || *p
== '\n' || *p
== '\r')
1159 input_line_pointer
= p
;
1163 if (*p
== '*' && (opmode
& (M6811_OP_DIRECT
| M6811_OP_IND16
)))
1165 mode
= M6811_OP_DIRECT
;
1170 if (!(opmode
& (M6811_OP_IMM8
| M6811_OP_IMM16
| M6811_OP_BITMASK
)))
1172 as_bad (_("Immediate operand is not allowed for operand %d."),
1177 mode
= M6811_OP_IMM16
;
1179 if (strncmp (p
, "%hi", 3) == 0)
1182 mode
|= M6811_OP_HIGH_ADDR
;
1184 else if (strncmp (p
, "%lo", 3) == 0)
1187 mode
|= M6811_OP_LOW_ADDR
;
1189 /* %page modifier is used to obtain only the page number
1190 of the address of a function. */
1191 else if (strncmp (p
, "%page", 5) == 0)
1194 mode
|= M6811_OP_PAGE_ADDR
;
1197 /* %addr modifier is used to obtain the physical address part
1198 of the function (16-bit). For 68HC12 the function will be
1199 mapped in the 16K window at 0x8000 and the value will be
1200 within that window (although the function address may not fit
1201 in 16-bit). See bfd/elf32-m68hc12.c for the translation. */
1202 else if (strncmp (p
, "%addr", 5) == 0)
1205 mode
|= M6811_OP_CALL_ADDR
;
1208 else if (*p
== '.' && (p
[1] == '+' || p
[1] == '-'))
1211 mode
= M6811_OP_JUMP_REL
;
1215 if (current_architecture
& cpu6811
)
1216 as_bad (_("Indirect indexed addressing is not valid for 68HC11."));
1219 mode
= M6812_OP_D_IDX
;
1220 p
= skip_whites (p
);
1222 else if (*p
== ',') /* Special handling of ,x and ,y. */
1225 input_line_pointer
= p
;
1227 reg
= register_name ();
1228 if (reg
!= REG_NONE
)
1231 oper
->exp
.X_op
= O_constant
;
1232 oper
->exp
.X_add_number
= 0;
1233 oper
->mode
= M6812_OP_IDX
;
1236 as_bad (_("Spurious `,' or bad indirect register addressing mode."));
1239 /* Handle 68HC12 page specification in 'call foo,%page(bar)'. */
1240 else if ((opmode
& M6812_OP_PAGE
) && strncmp (p
, "%page", 5) == 0)
1243 mode
= M6811_OP_PAGE_ADDR
| M6812_OP_PAGE
| M6811_OP_IND16
;
1245 input_line_pointer
= p
;
1247 if (mode
== M6811_OP_NONE
|| mode
== M6812_OP_D_IDX
)
1248 reg
= register_name ();
1252 if (reg
!= REG_NONE
)
1254 p
= skip_whites (input_line_pointer
);
1255 if (*p
== ']' && mode
== M6812_OP_D_IDX
)
1258 (_("Missing second register or offset for indexed-indirect mode."));
1263 oper
->mode
= mode
| M6812_OP_REG
;
1266 if (mode
== M6812_OP_D_IDX
)
1268 as_bad (_("Missing second register for indexed-indirect mode."));
1275 input_line_pointer
= p
;
1276 reg
= register_name ();
1277 if (reg
!= REG_NONE
)
1279 p
= skip_whites (input_line_pointer
);
1280 if (mode
== M6812_OP_D_IDX
)
1284 as_bad (_("Missing `]' to close indexed-indirect mode."));
1288 oper
->mode
= M6812_OP_D_IDX
;
1290 input_line_pointer
= p
;
1298 /* In MRI mode, isolate the operand because we can't distinguish
1299 operands from comments. */
1304 p
= skip_whites (p
);
1305 while (*p
&& *p
!= ' ' && *p
!= '\t')
1314 /* Parse as an expression. */
1315 expression (&oper
->exp
);
1324 expression (&oper
->exp
);
1327 if (oper
->exp
.X_op
== O_illegal
)
1329 as_bad (_("Illegal operand."));
1332 else if (oper
->exp
.X_op
== O_absent
)
1334 as_bad (_("Missing operand."));
1338 p
= input_line_pointer
;
1340 if (mode
== M6811_OP_NONE
|| mode
== M6811_OP_DIRECT
1341 || mode
== M6812_OP_D_IDX
)
1343 p
= skip_whites (input_line_pointer
);
1347 int possible_mode
= M6811_OP_NONE
;
1348 char *old_input_line
;
1353 /* 68HC12 pre increment or decrement. */
1354 if (mode
== M6811_OP_NONE
)
1358 possible_mode
= M6812_PRE_DEC
;
1363 possible_mode
= M6812_PRE_INC
;
1366 p
= skip_whites (p
);
1368 input_line_pointer
= p
;
1369 reg
= register_name ();
1371 /* Backtrack if we have a valid constant expression and
1372 it does not correspond to the offset of the 68HC12 indexed
1373 addressing mode (as in N,x). */
1374 if (reg
== REG_NONE
&& mode
== M6811_OP_NONE
1375 && possible_mode
!= M6811_OP_NONE
)
1377 oper
->mode
= M6811_OP_IND16
| M6811_OP_JUMP_REL
;
1378 input_line_pointer
= skip_whites (old_input_line
);
1382 if (possible_mode
!= M6811_OP_NONE
)
1383 mode
= possible_mode
;
1385 if ((current_architecture
& cpu6811
)
1386 && possible_mode
!= M6811_OP_NONE
)
1387 as_bad (_("Pre-increment mode is not valid for 68HC11"));
1389 if (which
== 0 && opmode
& M6812_OP_IDX_P2
1390 && reg
!= REG_X
&& reg
!= REG_Y
1391 && reg
!= REG_PC
&& reg
!= REG_SP
)
1394 input_line_pointer
= p
;
1397 if (reg
== REG_NONE
&& mode
!= M6811_OP_DIRECT
1398 && !(mode
== M6811_OP_NONE
&& opmode
& M6811_OP_IND16
))
1400 as_bad (_("Wrong register in register indirect mode."));
1403 if (mode
== M6812_OP_D_IDX
)
1405 p
= skip_whites (input_line_pointer
);
1408 as_bad (_("Missing `]' to close register indirect operand."));
1411 input_line_pointer
= p
;
1413 oper
->mode
= M6812_OP_D_IDX_2
;
1416 if (reg
!= REG_NONE
)
1419 if (mode
== M6811_OP_NONE
)
1421 p
= input_line_pointer
;
1424 mode
= M6812_POST_DEC
;
1426 if (current_architecture
& cpu6811
)
1428 (_("Post-decrement mode is not valid for 68HC11."));
1432 mode
= M6812_POST_INC
;
1434 if (current_architecture
& cpu6811
)
1436 (_("Post-increment mode is not valid for 68HC11."));
1439 mode
= M6812_OP_IDX
;
1441 input_line_pointer
= p
;
1444 mode
|= M6812_OP_IDX
;
1449 input_line_pointer
= old_input_line
;
1452 if (mode
== M6812_OP_D_IDX_2
)
1454 as_bad (_("Invalid indexed indirect mode."));
1459 /* If the mode is not known until now, this is either a label
1460 or an indirect address. */
1461 if (mode
== M6811_OP_NONE
)
1462 mode
= M6811_OP_IND16
| M6811_OP_JUMP_REL
;
1464 p
= input_line_pointer
;
1465 while (*p
== ' ' || *p
== '\t')
1467 input_line_pointer
= p
;
1473 #define M6812_AUTO_INC_DEC (M6812_PRE_INC | M6812_PRE_DEC \
1474 | M6812_POST_INC | M6812_POST_DEC)
1476 /* Checks that the number 'num' fits for a given mode. */
1478 check_range (long num
, int mode
)
1480 if (current_architecture
== cpuxgate
)
1485 return (num
>= 0 && num
<= 7) ? 1 : 0;
1487 case M68XG_OP_R_IMM4
:
1488 return (num
>= 0 && num
<= 15) ? 1 : 0;
1490 case M68XG_OP_R_R_OFFS5
:
1491 return (num
>= 0 && num
<= 31) ? 1 : 0;
1493 case M68XG_OP_R_IMM8
:
1494 return (num
>= 0 && num
<= 255) ? 1 : 0;
1496 case M68XG_OP_R_IMM16
:
1497 return (num
>= 0 && num
<= 65535) ? 1 : 0;
1499 case M68XG_OP_B_MARKER
:
1500 return (num
>= -512 && num
<= 511) ? 1 : 0;
1502 case M68XG_OP_BRA_MARKER
:
1503 return (num
>= -1024 && num
<= 1023) ? 1 : 0;
1511 /* Auto increment and decrement are ok for [-8..8] without 0. */
1512 if (mode
& M6812_AUTO_INC_DEC
)
1513 return (num
!= 0 && num
<= 8 && num
>= -8);
1515 /* The 68HC12 supports 5, 9 and 16-bit offsets. */
1516 if (mode
& (M6812_INDEXED_IND
| M6812_INDEXED
| M6812_OP_IDX
))
1517 mode
= M6811_OP_IND16
;
1519 if (mode
& M6812_OP_JUMP_REL16
)
1520 mode
= M6811_OP_IND16
;
1522 mode
&= ~M6811_OP_BRANCH
;
1527 case M6811_OP_DIRECT
:
1528 return (num
>= 0 && num
<= 255) ? 1 : 0;
1530 case M6811_OP_BITMASK
:
1533 return (((num
& 0xFFFFFF00) == 0) || ((num
& 0xFFFFFF00) == 0xFFFFFF00))
1536 case M6811_OP_JUMP_REL
:
1537 return (num
>= -128 && num
<= 127) ? 1 : 0;
1539 case M6811_OP_IND16
:
1540 case M6811_OP_IND16
| M6812_OP_PAGE
:
1541 case M6811_OP_IMM16
:
1542 return (((num
& 0xFFFF0000) == 0) || ((num
& 0xFFFF0000) == 0xFFFF0000))
1545 case M6812_OP_IBCC_MARKER
:
1546 case M6812_OP_TBCC_MARKER
:
1547 case M6812_OP_DBCC_MARKER
:
1548 return (num
>= -256 && num
<= 255) ? 1 : 0;
1550 case M6812_OP_TRAP_ID
:
1551 return ((num
>= 0x30 && num
<= 0x39)
1552 || (num
>= 0x40 && num
<= 0x0ff)) ? 1 : 0;
1560 /* Gas fixup generation. */
1562 /* Put a 1 byte expression described by 'oper'. If this expression contains
1563 unresolved symbols, generate an 8-bit fixup. */
1565 fixup8 (expressionS
*oper
, int mode
, int opmode
)
1571 if (oper
->X_op
== O_constant
)
1573 if (mode
& M6812_OP_TRAP_ID
1574 && !check_range (oper
->X_add_number
, M6812_OP_TRAP_ID
))
1576 static char trap_id_warn_once
= 0;
1578 as_bad (_("Trap id `%ld' is out of range."), oper
->X_add_number
);
1579 if (trap_id_warn_once
== 0)
1581 trap_id_warn_once
= 1;
1582 as_bad (_("Trap id must be within [0x30..0x39] or [0x40..0xff]."));
1586 if (!(mode
& M6812_OP_TRAP_ID
)
1587 && !check_range (oper
->X_add_number
, mode
))
1589 as_bad (_("Operand out of 8-bit range: `%ld'."), oper
->X_add_number
);
1591 number_to_chars_bigendian (f
, oper
->X_add_number
& 0x0FF, 1);
1593 else if (oper
->X_op
!= O_register
)
1595 if (mode
& M6812_OP_TRAP_ID
)
1596 as_bad (_("The trap id must be a constant."));
1598 if (mode
== M6811_OP_JUMP_REL
)
1602 fixp
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 1,
1603 oper
, TRUE
, BFD_RELOC_8_PCREL
);
1604 fixp
->fx_pcrel_adjust
= 1;
1611 /* Now create an 8-bit fixup. If there was some %hi, %lo
1612 or %page modifier, generate the reloc accordingly. */
1613 if (opmode
& M6811_OP_HIGH_ADDR
)
1614 reloc
= BFD_RELOC_M68HC11_HI8
;
1615 else if (opmode
& M6811_OP_LOW_ADDR
)
1616 reloc
= BFD_RELOC_M68HC11_LO8
;
1617 else if (opmode
& M6811_OP_PAGE_ADDR
)
1618 reloc
= BFD_RELOC_M68HC11_PAGE
;
1620 reloc
= BFD_RELOC_8
;
1622 fixp
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 1,
1623 oper
, FALSE
, reloc
);
1624 if (reloc
!= BFD_RELOC_8
)
1625 fixp
->fx_no_overflow
= 1;
1627 number_to_chars_bigendian (f
, 0, 1);
1631 as_fatal (_("Operand `%x' not recognized in fixup8."), oper
->X_op
);
1635 /* Put a 2 byte expression described by 'oper'. If this expression contains
1636 unresolved symbols, generate a 16-bit fixup. */
1638 fixup16 (expressionS
*oper
, int mode
, int opmode ATTRIBUTE_UNUSED
)
1644 if (oper
->X_op
== O_constant
)
1646 if (!check_range (oper
->X_add_number
, mode
))
1648 as_bad (_("Operand out of 16-bit range: `%ld'."),
1649 oper
->X_add_number
);
1651 number_to_chars_bigendian (f
, oper
->X_add_number
& 0x0FFFF, 2);
1653 else if (oper
->X_op
!= O_register
)
1658 if ((opmode
& M6811_OP_CALL_ADDR
) && (mode
& M6811_OP_IMM16
))
1659 reloc
= BFD_RELOC_M68HC11_LO16
;
1660 else if (mode
& M6812_OP_JUMP_REL16
)
1661 reloc
= BFD_RELOC_16_PCREL
;
1662 else if (mode
& M6812_OP_PAGE
)
1663 reloc
= BFD_RELOC_M68HC11_LO16
;
1665 reloc
= BFD_RELOC_16
;
1667 /* Now create a 16-bit fixup. */
1668 fixp
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 2,
1670 reloc
== BFD_RELOC_16_PCREL
,
1672 number_to_chars_bigendian (f
, 0, 2);
1673 if (reloc
== BFD_RELOC_16_PCREL
)
1674 fixp
->fx_pcrel_adjust
= 2;
1675 if (reloc
== BFD_RELOC_M68HC11_LO16
)
1676 fixp
->fx_no_overflow
= 1;
1680 as_fatal (_("Operand `%x' not recognized in fixup16."), oper
->X_op
);
1684 /* Put a 3 byte expression described by 'oper'. If this expression contains
1685 unresolved symbols, generate a 24-bit fixup. */
1687 fixup24 (expressionS
*oper
, int mode
, int opmode ATTRIBUTE_UNUSED
)
1693 if (oper
->X_op
== O_constant
)
1695 if (!check_range (oper
->X_add_number
, mode
))
1697 as_bad (_("Operand out of 16-bit range: `%ld'."),
1698 oper
->X_add_number
);
1700 number_to_chars_bigendian (f
, oper
->X_add_number
& 0x0FFFFFF, 3);
1702 else if (oper
->X_op
!= O_register
)
1704 /* Now create a 24-bit fixup. */
1705 fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 3,
1706 oper
, FALSE
, BFD_RELOC_M68HC11_24
);
1707 number_to_chars_bigendian (f
, 0, 3);
1711 as_fatal (_("Operand `%x' not recognized in fixup16."), oper
->X_op
);
1715 /* XGATE Put a 1 byte expression described by 'oper'. If this expression
1716 containts unresolved symbols, generate an 8-bit fixup. */
1718 fixup8_xg (expressionS
*oper
, int mode
, int opmode
)
1724 if (oper
->X_op
== O_constant
)
1729 if ((opmode
& M6811_OP_HIGH_ADDR
) || (opmode
& M6811_OP_LOW_ADDR
))
1731 if (opmode
& M6811_OP_HIGH_ADDR
)
1732 reloc
= BFD_RELOC_M68HC11_HI8
;
1734 reloc
= BFD_RELOC_M68HC11_LO8
;
1736 fixp
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 1,
1737 oper
, FALSE
, reloc
);
1738 fixp
->fx_no_overflow
= 1;
1739 number_to_chars_bigendian (f
, 0, 1);
1743 if (!(check_range (oper
->X_add_number
, mode
)))
1744 as_bad (_("Operand out of 8-bit range: `%ld'."),
1745 oper
->X_add_number
);
1746 number_to_chars_bigendian (f
, oper
->X_add_number
& 0x0FF, 1);
1749 else if (oper
->X_op
!= O_register
)
1751 if (mode
== M68XG_OP_REL9
)
1755 /* Future improvement:
1756 This fixup/reloc isn't adding on constants to symbols. */
1757 fixp
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
-1, 2,
1758 oper
, TRUE
, BFD_RELOC_M68HC12_9_PCREL
);
1759 fixp
->fx_pcrel_adjust
= 1;
1761 else if (mode
== M68XG_OP_REL10
)
1765 /* Future improvement:
1766 This fixup/reloc isn't adding on constants to symbols. */
1767 fixp
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
-1, 2,
1768 oper
, TRUE
, BFD_RELOC_M68HC12_10_PCREL
);
1769 fixp
->fx_pcrel_adjust
= 1;
1776 /* Now create an 8-bit fixup. If there was some %hi, %lo
1777 modifier, generate the reloc accordingly. */
1778 if (opmode
& M6811_OP_HIGH_ADDR
)
1779 reloc
= BFD_RELOC_M68HC11_HI8
;
1780 else if (opmode
& M6811_OP_LOW_ADDR
)
1781 reloc
= BFD_RELOC_M68HC11_LO8
;
1783 reloc
= BFD_RELOC_8
;
1785 fixp
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 1,
1786 oper
, FALSE
, reloc
);
1787 if (reloc
!= BFD_RELOC_8
)
1788 fixp
->fx_no_overflow
= 1;
1790 number_to_chars_bigendian (f
, 0, 1);
1793 as_fatal (_("Operand `%x' not recognized in fixup8."), oper
->X_op
);
1796 /* 68HC11 and 68HC12 code generation. */
1798 /* Translate the short branch/bsr instruction into a long branch. */
1800 static unsigned char
1801 convert_branch (unsigned char code
)
1803 if (IS_OPCODE (code
, M6812_BSR
))
1805 else if (IS_OPCODE (code
, M6811_BSR
))
1807 else if (IS_OPCODE (code
, M6811_BRA
))
1808 return (current_architecture
& cpu6812
) ? M6812_JMP
: M6811_JMP
;
1810 as_fatal (_("Unexpected branch conversion with `%x'"), code
);
1812 /* Keep gcc happy. */
1816 /* Start a new insn that contains at least 'size' bytes. Record the
1817 line information of that insn in the dwarf2 debug sections. */
1819 m68hc11_new_insn (int size
)
1823 f
= frag_more (size
);
1825 dwarf2_emit_insn (size
);
1830 /* Builds a jump instruction (bra, bcc, bsr). */
1832 build_jump_insn (struct m68hc11_opcode
*opcode
, operand operands
[],
1833 int nb_operands
, int jmp_mode
)
1839 /* The relative branch conversion is not supported for
1841 gas_assert ((opcode
->format
& M6811_OP_BITMASK
) == 0);
1842 gas_assert (nb_operands
== 1);
1843 gas_assert (operands
[0].reg1
== REG_NONE
&& operands
[0].reg2
== REG_NONE
);
1845 code
= opcode
->opcode
;
1847 n
= operands
[0].exp
.X_add_number
;
1849 /* Turn into a long branch:
1850 - when force long branch option (and not for jbcc pseudos),
1851 - when jbcc and the constant is out of -128..127 range,
1852 - when branch optimization is allowed and branch out of range. */
1853 if ((jmp_mode
== 0 && flag_force_long_jumps
)
1854 || (operands
[0].exp
.X_op
== O_constant
1855 && (!check_range (n
, opcode
->format
) &&
1856 (jmp_mode
== 1 || flag_fixed_branches
== 0))))
1858 fix_new (frag_now
, frag_now_fix (), 0,
1859 &abs_symbol
, 0, 1, BFD_RELOC_M68HC11_RL_JUMP
);
1861 if (code
== M6811_BSR
|| code
== M6811_BRA
|| code
== M6812_BSR
)
1863 code
= convert_branch (code
);
1865 f
= m68hc11_new_insn (1);
1866 number_to_chars_bigendian (f
, code
, 1);
1868 else if (current_architecture
& cpu6812
)
1870 /* 68HC12: translate the bcc into a lbcc. */
1871 f
= m68hc11_new_insn (2);
1872 number_to_chars_bigendian (f
, M6811_OPCODE_PAGE2
, 1);
1873 number_to_chars_bigendian (f
+ 1, code
, 1);
1874 fixup16 (&operands
[0].exp
, M6812_OP_JUMP_REL16
,
1875 M6812_OP_JUMP_REL16
);
1880 /* 68HC11: translate the bcc into b!cc +3; jmp <L>. */
1881 f
= m68hc11_new_insn (3);
1883 number_to_chars_bigendian (f
, code
, 1);
1884 number_to_chars_bigendian (f
+ 1, 3, 1);
1885 number_to_chars_bigendian (f
+ 2, M6811_JMP
, 1);
1887 fixup16 (&operands
[0].exp
, M6811_OP_IND16
, M6811_OP_IND16
);
1891 /* Branch with a constant that must fit in 8-bits. */
1892 if (operands
[0].exp
.X_op
== O_constant
)
1894 if (!check_range (n
, opcode
->format
))
1896 as_bad (_("Operand out of range for a relative branch: `%ld'"),
1899 else if (opcode
->format
& M6812_OP_JUMP_REL16
)
1901 f
= m68hc11_new_insn (4);
1902 number_to_chars_bigendian (f
, M6811_OPCODE_PAGE2
, 1);
1903 number_to_chars_bigendian (f
+ 1, code
, 1);
1904 number_to_chars_bigendian (f
+ 2, n
& 0x0ffff, 2);
1908 f
= m68hc11_new_insn (2);
1909 number_to_chars_bigendian (f
, code
, 1);
1910 number_to_chars_bigendian (f
+ 1, n
& 0x0FF, 1);
1913 else if (opcode
->format
& M6812_OP_JUMP_REL16
)
1915 fix_new (frag_now
, frag_now_fix (), 0,
1916 &abs_symbol
, 0, 1, BFD_RELOC_M68HC11_RL_JUMP
);
1918 f
= m68hc11_new_insn (2);
1919 number_to_chars_bigendian (f
, M6811_OPCODE_PAGE2
, 1);
1920 number_to_chars_bigendian (f
+ 1, code
, 1);
1921 fixup16 (&operands
[0].exp
, M6812_OP_JUMP_REL16
, M6812_OP_JUMP_REL16
);
1927 fix_new (frag_now
, frag_now_fix (), 0,
1928 &abs_symbol
, 0, 1, BFD_RELOC_M68HC11_RL_JUMP
);
1930 /* Branch offset must fit in 8-bits, don't do some relax. */
1931 if (jmp_mode
== 0 && flag_fixed_branches
)
1933 op
= m68hc11_new_insn (1);
1934 number_to_chars_bigendian (op
, code
, 1);
1935 fixup8 (&operands
[0].exp
, M6811_OP_JUMP_REL
, M6811_OP_JUMP_REL
);
1938 /* bra/bsr made be changed into jmp/jsr. */
1939 else if (code
== M6811_BSR
|| code
== M6811_BRA
|| code
== M6812_BSR
)
1941 /* Allocate worst case storage. */
1942 op
= m68hc11_new_insn (3);
1943 number_to_chars_bigendian (op
, code
, 1);
1944 number_to_chars_bigendian (op
+ 1, 0, 1);
1945 frag_variant (rs_machine_dependent
, 1, 1,
1946 ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_UNDF
),
1947 operands
[0].exp
.X_add_symbol
, (offsetT
) n
,
1950 else if (current_architecture
& cpu6812
)
1952 op
= m68hc11_new_insn (2);
1953 number_to_chars_bigendian (op
, code
, 1);
1954 number_to_chars_bigendian (op
+ 1, 0, 1);
1955 frag_var (rs_machine_dependent
, 2, 2,
1956 ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
, STATE_UNDF
),
1957 operands
[0].exp
.X_add_symbol
, (offsetT
) n
, op
);
1961 op
= m68hc11_new_insn (2);
1962 number_to_chars_bigendian (op
, code
, 1);
1963 number_to_chars_bigendian (op
+ 1, 0, 1);
1964 frag_var (rs_machine_dependent
, 3, 3,
1965 ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
, STATE_UNDF
),
1966 operands
[0].exp
.X_add_symbol
, (offsetT
) n
, op
);
1971 /* Builds a dbne/dbeq/tbne/tbeq instruction. */
1973 build_dbranch_insn (struct m68hc11_opcode
*opcode
, operand operands
[],
1974 int nb_operands
, int jmp_mode
)
1980 /* The relative branch conversion is not supported for
1982 gas_assert ((opcode
->format
& M6811_OP_BITMASK
) == 0);
1983 gas_assert (nb_operands
== 2);
1984 gas_assert (operands
[0].reg1
!= REG_NONE
);
1986 code
= opcode
->opcode
& 0x0FF;
1988 f
= m68hc11_new_insn (1);
1989 number_to_chars_bigendian (f
, code
, 1);
1991 n
= operands
[1].exp
.X_add_number
;
1992 code
= operands
[0].reg1
;
1994 if (operands
[0].reg1
== REG_NONE
|| operands
[0].reg1
== REG_CCR
1995 || operands
[0].reg1
== REG_PC
)
1996 as_bad (_("Invalid register for dbcc/tbcc instruction."));
1998 if (opcode
->format
& M6812_OP_IBCC_MARKER
)
2000 else if (opcode
->format
& M6812_OP_TBCC_MARKER
)
2003 if (!(opcode
->format
& M6812_OP_EQ_MARKER
))
2006 /* Turn into a long branch:
2007 - when force long branch option (and not for jbcc pseudos),
2008 - when jdbcc and the constant is out of -256..255 range,
2009 - when branch optimization is allowed and branch out of range. */
2010 if ((jmp_mode
== 0 && flag_force_long_jumps
)
2011 || (operands
[1].exp
.X_op
== O_constant
2012 && (!check_range (n
, M6812_OP_IBCC_MARKER
) &&
2013 (jmp_mode
== 1 || flag_fixed_branches
== 0))))
2017 number_to_chars_bigendian (f
, code
, 1);
2018 number_to_chars_bigendian (f
+ 1, M6812_JMP
, 1);
2019 fixup16 (&operands
[0].exp
, M6811_OP_IND16
, M6811_OP_IND16
);
2023 /* Branch with a constant that must fit in 9-bits. */
2024 if (operands
[1].exp
.X_op
== O_constant
)
2026 if (!check_range (n
, M6812_OP_IBCC_MARKER
))
2028 as_bad (_("Operand out of range for a relative branch: `%ld'"),
2037 number_to_chars_bigendian (f
, code
, 1);
2038 number_to_chars_bigendian (f
+ 1, n
& 0x0FF, 1);
2043 /* Branch offset must fit in 8-bits, don't do some relax. */
2044 if (jmp_mode
== 0 && flag_fixed_branches
)
2046 fixup8 (&operands
[0].exp
, M6811_OP_JUMP_REL
, M6811_OP_JUMP_REL
);
2052 number_to_chars_bigendian (f
, code
, 1);
2053 number_to_chars_bigendian (f
+ 1, 0, 1);
2054 frag_var (rs_machine_dependent
, 3, 3,
2055 ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_UNDF
),
2056 operands
[1].exp
.X_add_symbol
, (offsetT
) n
, f
);
2061 #define OP_EXTENDED (M6811_OP_PAGE2 | M6811_OP_PAGE3 | M6811_OP_PAGE4)
2063 /* Assemble the post index byte for 68HC12 extended addressing modes. */
2066 build_indexed_byte (operand
*op
, int format ATTRIBUTE_UNUSED
, int move_insn
)
2068 unsigned char byte
= 0;
2073 val
= op
->exp
.X_add_number
;
2075 if (mode
& M6812_AUTO_INC_DEC
)
2078 if (mode
& (M6812_POST_INC
| M6812_POST_DEC
))
2081 if (op
->exp
.X_op
== O_constant
)
2083 if (!check_range (val
, mode
))
2084 as_bad (_("Increment/decrement value is out of range: `%ld'."),
2087 if (mode
& (M6812_POST_INC
| M6812_PRE_INC
))
2088 byte
|= (val
- 1) & 0x07;
2090 byte
|= (8 - ((val
) & 7)) | 0x8;
2096 as_fatal (_("Expecting a register."));
2111 as_bad (_("Invalid register for post/pre increment."));
2116 number_to_chars_bigendian (f
, byte
, 1);
2120 if (mode
& (M6812_OP_IDX
| M6812_OP_D_IDX_2
))
2141 as_bad (_("Invalid register."));
2145 if (op
->exp
.X_op
== O_constant
)
2147 if (!check_range (val
, M6812_OP_IDX
))
2148 as_bad (_("Offset out of 16-bit range: %ld."), val
);
2150 if (move_insn
&& !(val
>= -16 && val
<= 15)
2151 && ((!(mode
& M6812_OP_IDX
) && !(mode
& M6812_OP_D_IDX_2
))
2152 || !(current_architecture
& cpu9s12x
)))
2154 as_bad (_("Offset out of 5-bit range for movw/movb insn: %ld."),
2159 if (val
>= -16 && val
<= 15 && !(mode
& M6812_OP_D_IDX_2
))
2164 number_to_chars_bigendian (f
, byte
, 1);
2167 else if (val
>= -256 && val
<= 255 && !(mode
& M6812_OP_D_IDX_2
))
2174 number_to_chars_bigendian (f
, byte
, 1);
2175 number_to_chars_bigendian (f
+ 1, val
& 0x0FF, 1);
2181 if (mode
& M6812_OP_D_IDX_2
)
2187 number_to_chars_bigendian (f
, byte
, 1);
2188 number_to_chars_bigendian (f
+ 1, val
& 0x0FFFF, 2);
2193 if (mode
& M6812_OP_D_IDX_2
)
2195 byte
= (byte
<< 3) | 0xe3;
2197 number_to_chars_bigendian (f
, byte
, 1);
2199 fixup16 (&op
->exp
, 0, 0);
2201 else if (op
->reg1
!= REG_PC
)
2207 number_to_chars_bigendian (f
, byte
, 1);
2208 sym
= op
->exp
.X_add_symbol
;
2209 off
= op
->exp
.X_add_number
;
2210 if (op
->exp
.X_op
!= O_symbol
)
2212 sym
= make_expr_symbol (&op
->exp
);
2216 /* movb/movw cannot be relaxed. */
2219 if ((mode
& M6812_OP_IDX
) && (current_architecture
& cpu9s12x
))
2221 /* Must treat as a 16bit relocate as size of final result is unknown. */
2225 number_to_chars_bigendian (f
, byte
, 1);
2226 fix_new (frag_now
, f
- frag_now
->fr_literal
, 2,
2227 sym
, off
, 0, BFD_RELOC_M68HC12_16B
);
2233 /* Non-S12X will fail at relocate stage if offset out of range. */
2235 number_to_chars_bigendian (f
, byte
, 1);
2236 fix_new (frag_now
, f
- frag_now
->fr_literal
, 1,
2237 sym
, off
, 0, BFD_RELOC_M68HC12_5B
);
2243 number_to_chars_bigendian (f
, byte
, 1);
2244 frag_var (rs_machine_dependent
, 2, 2,
2245 ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_UNDF
),
2253 /* movb/movw cannot be relaxed. */
2257 number_to_chars_bigendian (f
, byte
, 1);
2258 fix_new (frag_now
, f
- frag_now
->fr_literal
, 1,
2259 op
->exp
.X_add_symbol
, op
->exp
.X_add_number
, 0, BFD_RELOC_M68HC12_5B
);
2264 number_to_chars_bigendian (f
, byte
, 1);
2265 frag_var (rs_machine_dependent
, 2, 2,
2266 ENCODE_RELAX (STATE_INDEXED_PCREL
, STATE_UNDF
),
2267 op
->exp
.X_add_symbol
,
2268 op
->exp
.X_add_number
, f
);
2274 if (mode
& (M6812_OP_REG
| M6812_OP_D_IDX
))
2276 if (mode
& M6812_OP_D_IDX
)
2278 if (op
->reg1
!= REG_D
)
2279 as_bad (_("Expecting register D for indexed indirect mode."));
2280 if ((move_insn
) && (!(current_architecture
& cpu9s12x
)))
2281 as_bad (_("Indexed indirect mode is not allowed for movb/movw."));
2298 as_bad (_("Invalid accumulator register."));
2323 as_bad (_("Invalid indexed register."));
2327 number_to_chars_bigendian (f
, byte
, 1);
2331 fprintf (stderr
, "mode = 0x%x\nop->reg1 = 0x%x\nop->reg2 = 0x%x\n",
2332 mode
, op
->reg1
, op
->reg2
);
2333 as_fatal (_("Addressing mode not implemented yet."));
2337 /* Assemble the 68HC12 register mode byte. */
2339 build_reg_mode (operand
*op
, int format
)
2344 if ((format
& M6812_OP_SEX_MARKER
)
2345 && (op
->reg1
!= REG_A
) && (op
->reg1
!= REG_B
) && (op
->reg1
!= REG_CCR
)
2346 && (!(current_architecture
& cpu9s12x
)))
2347 as_bad (_("Invalid source register for this instruction, use 'tfr'."));
2348 else if (op
->reg1
== REG_NONE
|| op
->reg1
== REG_PC
)
2349 as_bad (_("Invalid source register."));
2351 if (format
& M6812_OP_SEX_MARKER
2352 && op
->reg2
!= REG_D
2353 && op
->reg2
!= REG_X
&& op
->reg2
!= REG_Y
&& op
->reg2
!= REG_SP
)
2354 as_bad (_("Invalid destination register for this instruction, use 'tfr'."));
2355 else if (op
->reg2
== REG_NONE
|| op
->reg2
== REG_PC
)
2356 as_bad (_("Invalid destination register."));
2358 byte
= (op
->reg1
<< 4) | (op
->reg2
);
2359 if (format
& M6812_OP_EXG_MARKER
)
2362 if ((format
& M6812_OP_SEX_MARKER
)
2363 && (op
->reg1
== REG_D
) && (current_architecture
& cpu9s12x
))
2367 number_to_chars_bigendian (f
, byte
, 1);
2371 /* build_insn_xg takes a pointer to the opcode entry in the opcode table,
2372 the array of operand expressions and builds the corresponding instruction. */
2375 build_insn_xg (struct m68hc11_opcode
*opcode
,
2377 int nb_operands ATTRIBUTE_UNUSED
)
2382 /* Put the page code instruction if there is one. */
2383 format
= opcode
->format
;
2385 if (!(operands
[0].mode
& (M6811_OP_LOW_ADDR
| M6811_OP_HIGH_ADDR
)))
2386 /* Need to retain those two modes, but clear for others. */
2387 operands
[0].mode
= 0;
2389 if (format
& M68XG_OP_R_IMM8
)
2391 /* These opcodes are byte followed by imm8. */
2392 f
= m68hc11_new_insn (1);
2393 number_to_chars_bigendian (f
, opcode
->opcode
>> 8, 1);
2394 fixup8_xg (&operands
[0].exp
, format
, operands
[0].mode
);
2396 else if (format
& M68XG_OP_R_IMM16
)
2399 /* These opcodes expand into two imm8 instructions.
2400 Emit as low:high as per the Freescale datasheet.
2401 The linker requires them to be adjacent to handle the upper byte. */
2403 /* Build low byte. */
2404 f
= m68hc11_new_insn (1);
2405 number_to_chars_bigendian (f
, opcode
->opcode
>> 8, 1);
2406 operands
[0].mode
= M6811_OP_LOW_ADDR
;
2408 fixp
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 1,
2409 &operands
[0].exp
, FALSE
, BFD_RELOC_M68HC12_LO8XG
);
2410 fixp
->fx_no_overflow
= 1;
2411 number_to_chars_bigendian (f
, 0, 1);
2413 /* Build high byte. */
2414 f
= m68hc11_new_insn (1);
2415 number_to_chars_bigendian (f
, (opcode
->opcode
>> 8) | 0x08, 1);
2416 operands
[0].mode
= M6811_OP_HIGH_ADDR
;
2418 fixp
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 1,
2419 &operands
[0].exp
, FALSE
, BFD_RELOC_M68HC12_HI8XG
);
2420 fixp
->fx_no_overflow
= 1;
2421 number_to_chars_bigendian (f
, 0, 1);
2424 else if (format
& M68XG_OP_REL9
)
2426 f
= m68hc11_new_insn (1);
2427 number_to_chars_bigendian (f
, opcode
->opcode
>> 8, 1); /* High byte. */
2428 fixup8_xg (&operands
[0].exp
, format
, M68XG_OP_REL9
);
2430 else if (format
& M68XG_OP_REL10
)
2432 f
= m68hc11_new_insn (1);
2433 number_to_chars_bigendian (f
, opcode
->opcode
>> 8, 1); /* High byte. */
2434 fixup8_xg (&operands
[0].exp
, format
, M68XG_OP_REL10
);
2438 f
= m68hc11_new_insn (2);
2439 number_to_chars_bigendian (f
, opcode
->opcode
, 2);
2444 /* build_insn takes a pointer to the opcode entry in the opcode table,
2445 the array of operand expressions and builds the corresponding instruction.
2446 This operation only deals with non relative jumps insn (need special
2450 build_insn (struct m68hc11_opcode
*opcode
,
2452 int nb_operands ATTRIBUTE_UNUSED
)
2459 /* Put the page code instruction if there is one. */
2460 format
= opcode
->format
;
2462 if (format
& M6811_OP_BRANCH
)
2463 fix_new (frag_now
, frag_now_fix (), 0,
2464 &abs_symbol
, 0, 1, BFD_RELOC_M68HC11_RL_JUMP
);
2466 if (format
& OP_EXTENDED
)
2470 f
= m68hc11_new_insn (2);
2471 if (format
& M6811_OP_PAGE2
)
2472 page_code
= M6811_OPCODE_PAGE2
;
2473 else if (format
& M6811_OP_PAGE3
)
2474 page_code
= M6811_OPCODE_PAGE3
;
2476 page_code
= M6811_OPCODE_PAGE4
;
2478 number_to_chars_bigendian (f
, page_code
, 1);
2482 f
= m68hc11_new_insn (1);
2484 number_to_chars_bigendian (f
, opcode
->opcode
, 1);
2488 /* The 68HC12 movb and movw instructions are special. We have to handle
2489 them in a special way. */
2490 if (format
& (M6812_OP_IND16_P2
| M6812_OP_IDX_P2
))
2493 if (format
& M6812_OP_IDX
)
2495 build_indexed_byte (&operands
[0], format
, 1);
2497 format
&= ~M6812_OP_IDX
;
2499 if (format
& M6812_OP_IDX_P2
)
2501 build_indexed_byte (&operands
[1], format
, 1);
2503 format
&= ~M6812_OP_IDX_P2
;
2507 if (format
& (M6811_OP_DIRECT
| M6811_OP_IMM8
))
2509 fixup8 (&operands
[i
].exp
,
2510 format
& (M6811_OP_DIRECT
| M6811_OP_IMM8
| M6812_OP_TRAP_ID
),
2514 else if (IS_CALL_SYMBOL (format
) && nb_operands
== 1)
2516 format
&= ~M6812_OP_PAGE
;
2517 fixup24 (&operands
[i
].exp
, format
& M6811_OP_IND16
,
2521 else if (format
& (M6811_OP_IMM16
| M6811_OP_IND16
))
2523 fixup16 (&operands
[i
].exp
,
2524 format
& (M6811_OP_IMM16
| M6811_OP_IND16
| M6812_OP_PAGE
),
2528 else if (format
& (M6811_OP_IX
| M6811_OP_IY
))
2530 if ((format
& M6811_OP_IX
) && (operands
[0].reg1
!= REG_X
))
2531 as_bad (_("Invalid indexed register, expecting register X."));
2532 if ((format
& M6811_OP_IY
) && (operands
[0].reg1
!= REG_Y
))
2533 as_bad (_("Invalid indexed register, expecting register Y."));
2535 fixup8 (&operands
[0].exp
, M6811_OP_IX
, operands
[0].mode
);
2539 (M6812_OP_IDX
| M6812_OP_IDX_2
| M6812_OP_IDX_1
2540 | M6812_OP_D_IDX
| M6812_OP_D_IDX_2
))
2542 build_indexed_byte (&operands
[i
], format
, move_insn
);
2545 else if (format
& M6812_OP_REG
&& current_architecture
& cpu6812
)
2547 build_reg_mode (&operands
[i
], format
);
2550 if (format
& M6811_OP_BITMASK
)
2552 fixup8 (&operands
[i
].exp
, M6811_OP_BITMASK
, operands
[i
].mode
);
2555 if (format
& M6811_OP_JUMP_REL
)
2557 fixup8 (&operands
[i
].exp
, M6811_OP_JUMP_REL
, operands
[i
].mode
);
2559 else if (format
& M6812_OP_IND16_P2
)
2561 fixup16 (&operands
[1].exp
, M6811_OP_IND16
, operands
[1].mode
);
2563 if (format
& M6812_OP_PAGE
)
2565 fixup8 (&operands
[i
].exp
, M6812_OP_PAGE
, operands
[i
].mode
);
2569 /* Opcode identification and operand analysis. */
2571 /* find() gets a pointer to an entry in the opcode table. It must look at all
2572 opcodes with the same name and use the operands to choose the correct
2573 opcode. Returns the opcode pointer if there was a match and 0 if none. */
2574 static struct m68hc11_opcode
*
2575 find (struct m68hc11_opcode_def
*opc
, operand operands
[], int nb_operands
)
2578 struct m68hc11_opcode
*opcode
;
2579 struct m68hc11_opcode
*op_indirect
;
2582 opcode
= opc
->opcode
;
2584 /* Now search the opcode table table for one with operands
2585 that matches what we've got. */
2587 if (current_architecture
& cpuxgate
)
2589 /* Many XGATE insns are simple enough that we get an exact match. */
2590 for (pos
= match
= 0; match
== 0 && pos
< opc
->nb_modes
; pos
++, opcode
++)
2591 if (opcode
->format
== operands
[nb_operands
-1].mode
)
2599 /* Now search the opcode table table for one with operands
2600 that matches what we've got. We're only done if the operands matched so
2601 far AND there are no more to check. */
2602 for (pos
= match
= 0; match
== 0 && pos
< opc
->nb_modes
; pos
++, opcode
++)
2604 int poss_indirect
= 0;
2605 long format
= opcode
->format
;
2609 if (opcode
->format
& M6811_OP_MASK
)
2611 if (opcode
->format
& M6811_OP_BITMASK
)
2613 if (opcode
->format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
2615 if (opcode
->format
& (M6812_OP_IND16_P2
| M6812_OP_IDX_P2
))
2617 if ((opcode
->format
& M6812_OP_PAGE
)
2618 && (!IS_CALL_SYMBOL (opcode
->format
) || nb_operands
== 2))
2621 for (i
= 0; expect
== nb_operands
&& i
< nb_operands
; i
++)
2623 int mode
= operands
[i
].mode
;
2625 if (mode
& M6811_OP_IMM16
)
2628 (M6811_OP_IMM8
| M6811_OP_IMM16
| M6811_OP_BITMASK
))
2632 if (mode
== M6811_OP_DIRECT
)
2634 if (format
& M6811_OP_DIRECT
)
2637 /* If the operand is a page 0 operand, remember a
2638 possible <abs-16> addressing mode. We mark
2639 this and continue to check other operands. */
2640 if (format
& M6811_OP_IND16
2641 && flag_strict_direct_addressing
&& op_indirect
== 0)
2648 if (mode
& M6811_OP_IND16
)
2650 if (i
== 0 && (format
& M6811_OP_IND16
) != 0)
2652 if (i
!= 0 && (format
& M6812_OP_PAGE
) != 0)
2654 if (i
!= 0 && (format
& M6812_OP_IND16_P2
) != 0)
2656 if (i
== 0 && (format
& M6811_OP_BITMASK
))
2659 if (mode
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
2661 if (format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
2664 if (mode
& M6812_OP_REG
)
2667 && (format
& M6812_OP_REG
)
2668 && (operands
[i
].reg2
== REG_NONE
))
2671 && (format
& M6812_OP_REG
)
2672 && (format
& M6812_OP_REG_2
)
2673 && (operands
[i
].reg2
!= REG_NONE
))
2676 && (format
& M6812_OP_IDX
)
2677 && (operands
[i
].reg2
!= REG_NONE
))
2680 && (format
& M6812_OP_IDX
)
2681 && (format
& (M6812_OP_IND16_P2
| M6812_OP_IDX_P2
)))
2684 && (format
& M6812_OP_IDX_P2
))
2688 if (mode
& M6812_OP_IDX
)
2690 if (format
& M6811_OP_IX
&& operands
[i
].reg1
== REG_X
)
2692 if (format
& M6811_OP_IY
&& operands
[i
].reg1
== REG_Y
)
2695 && format
& (M6812_OP_IDX
| M6812_OP_IDX_1
| M6812_OP_IDX_2
)
2696 && (operands
[i
].reg1
== REG_X
2697 || operands
[i
].reg1
== REG_Y
2698 || operands
[i
].reg1
== REG_SP
2699 || operands
[i
].reg1
== REG_PC
))
2701 if (i
== 1 && (format
& M6812_OP_IDX_P2
))
2704 if (mode
& format
& (M6812_OP_D_IDX
| M6812_OP_D_IDX_2
))
2709 if (mode
& M6812_AUTO_INC_DEC
)
2712 && format
& (M6812_OP_IDX
| M6812_OP_IDX_1
|
2715 if (i
== 1 && format
& M6812_OP_IDX_P2
)
2720 match
= i
== nb_operands
;
2722 /* Operands are ok but an operand uses page 0 addressing mode
2723 while the insn supports abs-16 mode. Keep a reference to this
2724 insns in case there is no insn supporting page 0 addressing. */
2725 if (match
&& poss_indirect
)
2727 op_indirect
= opcode
;
2734 /* Page 0 addressing is used but not supported by any insn.
2735 If absolute addresses are supported, we use that insn. */
2736 if (match
== 0 && op_indirect
)
2738 opcode
= op_indirect
;
2742 return match
? opcode
: 0;
2745 /* Find the real opcode and its associated operands. We use a progressive
2746 approach here. On entry, 'opc' points to the first opcode in the
2747 table that matches the opcode name in the source line. We try to
2748 isolate an operand, find a possible match in the opcode table.
2749 We isolate another operand if no match were found. The table 'operands'
2750 is filled while operands are recognized.
2752 Returns the opcode pointer that matches the opcode name in the
2753 source line and the associated operands. */
2754 static struct m68hc11_opcode
*
2755 find_opcode (struct m68hc11_opcode_def
*opc
, operand operands
[],
2758 struct m68hc11_opcode
*opcode
;
2761 if (opc
->max_operands
== 0)
2767 for (i
= 0; i
< opc
->max_operands
;)
2771 result
= get_operand (&operands
[i
], i
, opc
->format
);
2775 /* Special case where the bitmask of the bclr/brclr
2776 instructions is not introduced by #.
2777 Example: bclr 3,x $80. */
2778 if (i
== 1 && (opc
->format
& M6811_OP_BITMASK
)
2779 && (operands
[i
].mode
& M6811_OP_IND16
))
2781 operands
[i
].mode
= M6811_OP_IMM16
;
2786 if (i
>= opc
->min_operands
)
2788 opcode
= find (opc
, operands
, i
);
2790 /* Another special case for 'call foo,page' instructions.
2791 Since we support 'call foo' and 'call foo,page' we must look
2792 if the optional page specification is present otherwise we will
2793 assemble immediately and treat the page spec as garbage. */
2794 if (opcode
&& !(opcode
->format
& M6812_OP_PAGE
))
2797 if (opcode
&& *input_line_pointer
!= ',')
2801 if (*input_line_pointer
== ',')
2802 input_line_pointer
++;
2808 #define M6812_XBCC_MARKER (M6812_OP_TBCC_MARKER \
2809 | M6812_OP_DBCC_MARKER \
2810 | M6812_OP_IBCC_MARKER)
2812 /* Gas line assembler entry point. */
2814 /* This is the main entry point for the machine-dependent assembler. str
2815 points to a machine-dependent instruction. This function is supposed to
2816 emit the frags/bytes it assembles to. */
2818 md_assemble (char *str
)
2820 struct m68hc11_opcode_def
*opc
;
2821 struct m68hc11_opcode
*opcode
;
2823 struct m68hc11_opcode opcode_local
;
2824 unsigned char *op_start
, *op_end
;
2828 operand operands
[M6811_MAX_OPERANDS
];
2829 int nb_operands
= 0;
2830 int branch_optimize
= 0;
2833 /* Drop leading whitespace. */
2837 /* Find the opcode end and get the opcode in 'name'. The opcode is forced
2838 lower case (the opcode table only has lower case op-codes). */
2839 for (op_start
= op_end
= (unsigned char *) str
;
2840 *op_end
&& !is_end_of_line
[*op_end
] && *op_end
!= ' ';
2843 name
[nlen
] = TOLOWER (op_start
[nlen
]);
2845 if (nlen
== sizeof (name
) - 1)
2852 as_bad (_("No instruction or missing opcode."));
2856 if (current_architecture
== cpuxgate
)
2858 /* Find the opcode definition given its name. */
2859 opc
= (struct m68hc11_opcode_def
*) hash_find (m68hc11_hash
, name
);
2862 as_bad (_("Opcode `%s' is not recognized."), name
);
2866 /* Grab a local copy. */
2867 opcode_local
.name
= opc
->opcode
->name
;
2868 /* These will be incomplete where multiple variants exist. */
2869 opcode_local
.opcode
= opc
->opcode
->opcode
;
2870 opcode_local
.format
= opc
->opcode
->format
;
2872 save
= input_line_pointer
;
2873 input_line_pointer
= (char *) op_end
;
2875 if (opc
->format
== M68XG_OP_NONE
)
2877 /* No special handling required. */
2878 opcode_local
.format
= M68XG_OP_NONE
;
2879 build_insn_xg (opc
->opcode
, operands
, 0);
2883 /* Special handling of TFR. */
2884 if (strncmp (opc
->opcode
->name
, "tfr",3) == 0)
2886 /* There must be two operands with a comma. */
2887 input_line_pointer
= skip_whites (input_line_pointer
);
2888 operands
[0].reg1
= register_name ();
2889 if (operands
[0].reg1
== REG_NONE
)
2891 as_bad ("Invalid register\n");
2894 input_line_pointer
= skip_whites (input_line_pointer
);
2895 if (*input_line_pointer
!= ',')
2897 as_bad ("Missing comma.\n");
2900 input_line_pointer
++;
2901 input_line_pointer
= skip_whites (input_line_pointer
);
2902 operands
[1].reg1
= register_name ();
2903 if (operands
[1].reg1
== REG_NONE
)
2905 as_bad ("Invalid register\n");
2908 input_line_pointer
= skip_whites (input_line_pointer
);
2909 if (*input_line_pointer
!= '\n' && *input_line_pointer
)
2911 as_bad (_("Garbage at end of instruction: `%s'."),
2912 input_line_pointer
);
2915 if (operands
[1].reg1
== REG_CCR
) /* ,CCR */
2916 opc
->opcode
->opcode
= 0x00f8 | ( operands
[0].reg1
<< 8);
2917 else if (operands
[0].reg1
== REG_CCR
) /* CCR, */
2918 opc
->opcode
->opcode
= 0x00f9 | ( operands
[1].reg1
<< 8);
2919 else if (operands
[1].reg1
== REG_PC
) /* ,PC */
2920 opc
->opcode
->opcode
= 0x00fa | ( operands
[0].reg1
<< 8);
2923 as_bad ("Invalid operand to TFR\n");
2926 /* no special handling required */
2927 opcode_local
.format
= M68XG_OP_NONE
;
2928 opcode_local
.opcode
= opc
->opcode
->opcode
;
2929 build_insn_xg (&opcode_local
, operands
, 0);
2934 if (opc
->format
& M68XG_OP_IMM3
)
2936 /* Either IMM3 or R */
2937 input_line_pointer
= skip_whites (input_line_pointer
);
2938 if ((*input_line_pointer
== 'R') || (*input_line_pointer
== 'r'))
2940 operands
[0].reg1
= register_name ();
2941 if (operands
[0].reg1
== REG_NONE
)
2943 as_bad ("Invalid register\n");
2946 operands
[0].mode
= M68XG_OP_R
;
2947 /* One opcode has multiple modes, so find right one. */
2948 opcode
= find (opc
, operands
, 1);
2951 opcode_local
.opcode
= opcode
->opcode
2952 | (operands
[0].reg1
<< 8);
2953 opcode_local
.format
= M68XG_OP_NONE
;
2954 build_insn_xg (&opcode_local
, operands
, 1);
2957 as_bad ("No opcode found\n");
2963 if (*input_line_pointer
== '#')
2964 input_line_pointer
++;
2966 expression (&operands
[0].exp
);
2967 if (operands
[0].exp
.X_op
== O_illegal
)
2969 as_bad (_("Illegal operand."));
2972 else if (operands
[0].exp
.X_op
== O_absent
)
2974 as_bad (_("Missing operand."));
2978 if (check_range (operands
[0].exp
.X_add_number
,M68XG_OP_IMM3
))
2980 opcode_local
.opcode
|= (operands
[0].exp
.X_add_number
);
2981 operands
[0].mode
= M68XG_OP_IMM3
;
2983 opcode
= find (opc
, operands
, 1);
2986 opcode_local
.opcode
= opcode
->opcode
;
2988 |= (operands
[0].exp
.X_add_number
) << 8;
2989 opcode_local
.format
= M68XG_OP_NONE
;
2990 build_insn_xg (&opcode_local
, operands
, 1);
2993 as_bad ("No opcode found\n");
2999 as_bad ("Number out of range for IMM3\n");
3005 /* Special handling of SIF. */
3006 if (strncmp (opc
->opcode
->name
, "sif",3) == 0)
3008 /* Either OP_NONE or OP_RS. */
3009 if (*input_line_pointer
!= '\n')
3010 input_line_pointer
= skip_whites (input_line_pointer
);
3012 if ((*input_line_pointer
== '\n') || (*input_line_pointer
== '\r')
3013 || (*input_line_pointer
== '\0'))
3014 opc
->opcode
->opcode
= 0x0300;
3017 operands
[0].reg1
= register_name ();
3018 if (operands
[0].reg1
== REG_NONE
)
3020 as_bad ("Invalid register\n");
3023 opcode_local
.opcode
= 0x00f7 | (operands
[0].reg1
<< 8);
3025 opcode_local
.format
= M68XG_OP_NONE
;
3026 build_insn_xg (&opcode_local
, operands
, 0);
3030 /* SEX, PAR, JAL plus aliases NEG, TST, COM */
3031 if (opc
->format
& M68XG_OP_R
)
3033 input_line_pointer
= skip_whites (input_line_pointer
);
3034 operands
[0].reg1
= register_name ();
3035 if (operands
[0].reg1
== REG_NONE
)
3037 as_bad ("Invalid register\n");
3040 if ((*input_line_pointer
== '\n') || (*input_line_pointer
== '\r')
3041 || (*input_line_pointer
== '\0'))
3043 /* Likely to be OP R. */
3044 if (opc
->format
& M68XG_OP_R
)
3046 operands
[0].mode
= M68XG_OP_R
;
3048 opcode
= find (opc
, operands
, 1);
3051 if ((strncmp (opc
->opcode
->name
, "com",3) == 0)
3052 || (strncmp (opc
->opcode
->name
, "neg",3) == 0))
3053 /* Special case for com RD as alias for sub RD,R0,RS */
3054 /* Special case for neg RD as alias for sub RD,R0,RS */
3055 opcode_local
.opcode
= opcode
->opcode
3056 | (operands
[0].reg1
<< 8) | (operands
[0].reg1
<< 2);
3057 else if (strncmp (opc
->opcode
->name
, "tst",3) == 0)
3058 /* Special case for tst RS alias for sub R0, RS, R0 */
3059 opcode_local
.opcode
= opcode
->opcode
3060 | (operands
[0].reg1
<< 5);
3062 opcode_local
.opcode
|= (operands
[0].reg1
<< 8);
3064 opcode_local
.format
= M68XG_OP_NONE
;
3065 build_insn_xg (&opcode_local
, operands
, 0);
3068 as_bad ("No valid mode found\n");
3074 if (opc
->format
& (M68XG_OP_REL9
| M68XG_OP_REL10
))
3076 opcode_local
.format
= opc
->format
;
3077 input_line_pointer
= skip_whites (input_line_pointer
);
3078 expression (&operands
[0].exp
);
3079 if (operands
[0].exp
.X_op
== O_illegal
)
3081 as_bad (_("Illegal operand."));
3084 else if (operands
[0].exp
.X_op
== O_absent
)
3086 as_bad (_("Missing operand."));
3089 opcode_local
.opcode
= opc
->opcode
->opcode
;
3090 build_insn_xg (&opcode_local
, operands
, 1);
3095 /* For other command formats, parse input line and determine the mode
3096 we are using as we go. */
3098 input_line_pointer
= skip_whites (input_line_pointer
);
3099 if ((*input_line_pointer
== '\n') || (*input_line_pointer
== '\r')
3100 || (*input_line_pointer
== '\0'))
3101 return; /* nothing left */
3103 if (*input_line_pointer
== '#')
3105 as_bad ("No register specified before hash\n");
3109 /* first operand is expected to be a register */
3110 if ((*input_line_pointer
== 'R') || (*input_line_pointer
== 'r'))
3112 operands
[0].reg1
= register_name ();
3113 if (operands
[0].reg1
== REG_NONE
)
3115 as_bad ("Invalid register\n");
3120 input_line_pointer
= skip_whites (input_line_pointer
);
3121 if (*input_line_pointer
!= ',')
3123 as_bad ("Missing operand\n");
3126 input_line_pointer
++;
3127 input_line_pointer
= skip_whites (input_line_pointer
);
3129 if (*input_line_pointer
== '#')
3131 /* Some kind of immediate mode, check if this is possible. */
3133 & (M68XG_OP_R_IMM8
| M68XG_OP_R_IMM16
| M68XG_OP_R_IMM4
)))
3134 as_bad ("Invalid immediate mode for `%s'", opc
->opcode
->name
);
3137 input_line_pointer
++;
3138 input_line_pointer
= skip_whites (input_line_pointer
);
3139 if (strncmp (input_line_pointer
, "%hi", 3) == 0)
3141 input_line_pointer
+= 3;
3142 operands
[0].mode
= M6811_OP_HIGH_ADDR
;
3144 else if (strncmp (input_line_pointer
, "%lo", 3) == 0)
3146 input_line_pointer
+= 3;
3147 operands
[0].mode
= M6811_OP_LOW_ADDR
;
3150 operands
[0].mode
= 0;
3152 expression (&operands
[0].exp
);
3153 if (operands
[0].exp
.X_op
== O_illegal
)
3155 as_bad (_("Illegal operand."));
3158 else if (operands
[0].exp
.X_op
== O_absent
)
3160 as_bad (_("Missing operand."));
3163 /* ok so far, can only be one mode */
3164 opcode_local
.format
= opc
->format
3165 & (M68XG_OP_R_IMM8
| M68XG_OP_R_IMM16
| M68XG_OP_R_IMM4
);
3166 if (opcode_local
.format
& M68XG_OP_R_IMM4
)
3168 operands
[0].mode
= M68XG_OP_R_IMM4
;
3169 /* same opcodes have multiple modes, so find right one */
3170 opcode
= find (opc
, operands
, 1);
3172 opcode_local
.opcode
= opcode
->opcode
3173 | (operands
[0].reg1
<< 8);
3175 if (operands
[0].exp
.X_op
!= O_constant
)
3176 as_bad ("Only constants supported at for IMM4 mode\n");
3180 (operands
[0].exp
.X_add_number
,M68XG_OP_R_IMM4
))
3182 |= (operands
[0].exp
.X_add_number
<< 4);
3184 as_bad ("Number out of range for IMM4\n");
3186 opcode_local
.format
= M68XG_OP_NONE
;
3188 else if (opcode_local
.format
& M68XG_OP_R_IMM16
)
3190 operands
[0].mode
= M68XG_OP_R_IMM16
;
3192 opcode
= find (opc
, operands
, 1);
3195 opcode_local
.opcode
= opcode
->opcode
3196 | (operands
[0].reg1
<< 8);
3201 opcode_local
.opcode
= opc
->opcode
->opcode
3202 | (operands
[0].reg1
<< 8);
3204 build_insn_xg (&opcode_local
, operands
, 1);
3207 else if ((*input_line_pointer
== 'R') || (*input_line_pointer
== 'r'))
3209 /* we've got as far as OP R, R */
3210 operands
[1].reg1
= register_name ();
3211 if (operands
[1].reg1
== REG_NONE
)
3213 as_bad ("Invalid register\n");
3216 if ((*input_line_pointer
== '\n') || (*input_line_pointer
== '\r')
3217 || (*input_line_pointer
== '\0'))
3219 /* looks like OP_R_R */
3220 if (opc
->format
& M68XG_OP_R_R
)
3222 operands
[0].mode
= M68XG_OP_R_R
;
3223 /* same opcodes have multiple modes, so find right one */
3224 opcode
= find (opc
, operands
, 1);
3227 if ((strncmp (opc
->opcode
->name
, "com",3) == 0)
3228 || (strncmp (opc
->opcode
->name
, "mov",3) == 0)
3229 || (strncmp (opc
->opcode
->name
, "neg",3) == 0))
3231 /* Special cases for:
3232 com RD, RS alias for xnor RD,R0,RS
3233 mov RD, RS alias for or RD, R0, RS
3234 neg RD, RS alias for sub RD, R0, RS */
3235 opcode_local
.opcode
= opcode
->opcode
3236 | (operands
[0].reg1
<< 8) | (operands
[1].reg1
<< 2);
3238 else if ((strncmp (opc
->opcode
->name
, "cmp",3) == 0)
3239 || (strncmp (opc
->opcode
->name
, "cpc",3) == 0))
3241 /* special cases for:
3242 cmp RS1, RS2 alias for sub R0, RS1, RS2
3243 cpc RS1, RS2 alias for sbc R0, RS1, RS2 */
3244 opcode_local
.opcode
= opcode
->opcode
3245 | (operands
[0].reg1
<< 5) | (operands
[1].reg1
<< 2);
3249 opcode_local
.opcode
= opcode
->opcode
3250 | (operands
[0].reg1
<< 8) | (operands
[1].reg1
<< 5);
3252 opcode_local
.format
= M68XG_OP_NONE
;
3253 build_insn_xg (&opcode_local
, operands
, 1);
3258 as_bad ("No valid mode found\n");
3264 if (*input_line_pointer
!= ',')
3266 as_bad (_("Missing operand."));
3269 input_line_pointer
++;
3270 input_line_pointer
= skip_whites (input_line_pointer
);
3271 if ((*input_line_pointer
== 'R') || (*input_line_pointer
== 'r'))
3273 operands
[2].reg1
= register_name ();
3274 if (operands
[2].reg1
== REG_NONE
)
3276 as_bad ("Invalid register\n");
3279 if (opc
->format
& M68XG_OP_R_R_R
)
3281 operands
[0].mode
= M68XG_OP_R_R_R
;
3283 opcode
= find (opc
, operands
, 1);
3286 opcode_local
.opcode
= opcode
->opcode
3287 | (operands
[0].reg1
<< 8) | (operands
[1].reg1
<< 5)
3288 | (operands
[2].reg1
<< 2);
3289 opcode_local
.format
= M68XG_OP_NONE
;
3290 build_insn_xg (&opcode_local
, operands
, 1);
3295 as_bad ("No valid mode found\n");
3300 else if (*input_line_pointer
== '(') /* Indexed modes */
3302 input_line_pointer
++;
3303 input_line_pointer
= skip_whites (input_line_pointer
);
3304 if ((*input_line_pointer
== 'R') || (*input_line_pointer
== 'r'))
3306 /* we've got as far as OP R, (R */
3307 operands
[1].reg1
= register_name ();
3308 if (operands
[1].reg1
== REG_NONE
)
3310 as_bad ("Invalid register\n");
3314 if ((*input_line_pointer
== '\n') || (*input_line_pointer
== '\r')
3315 || (*input_line_pointer
== '\0'))
3317 /* Looks like OP_R_R. */
3318 as_bad (_("Missing operand."));
3322 input_line_pointer
= skip_whites (input_line_pointer
);
3324 if (*input_line_pointer
!= ',')
3326 as_bad (_("Missing operand."));
3329 input_line_pointer
++;
3330 input_line_pointer
= skip_whites (input_line_pointer
);
3332 if (*input_line_pointer
== '#')
3334 input_line_pointer
++;
3335 input_line_pointer
= skip_whites (input_line_pointer
);
3336 expression (&operands
[0].exp
);
3337 if (operands
[0].exp
.X_op
== O_illegal
)
3339 as_bad (_("Illegal operand."));
3342 else if (operands
[0].exp
.X_op
== O_absent
)
3344 as_bad (_("Missing operand."));
3348 input_line_pointer
= skip_whites (input_line_pointer
);
3349 if (*input_line_pointer
!= ')')
3351 as_bad ("Missing `)' to close register indirect operand.");
3356 input_line_pointer
++;
3359 /* Ok so far, can only be one mode. */
3360 opcode_local
.format
= M68XG_OP_R_R_OFFS5
;
3361 operands
[0].mode
= M68XG_OP_R_R_OFFS5
;
3363 opcode
= find (opc
, operands
, 1);
3366 opcode_local
.opcode
= opcode
->opcode
3367 | (operands
[0].reg1
<< 8) | (operands
[1].reg1
<< 5);
3368 if (operands
[0].exp
.X_op
!= O_constant
)
3371 ("Only constants supported for indexed OFFS5 mode\n");
3375 if (check_range (operands
[0].exp
.X_add_number
,
3376 M68XG_OP_R_R_OFFS5
))
3379 |= (operands
[0].exp
.X_add_number
);
3380 opcode_local
.format
= M68XG_OP_NONE
;
3381 build_insn_xg (&opcode_local
, operands
, 1);
3385 as_bad ("Number out of range for OFFS5\n");
3392 operands
[0].mode
= M68XG_OP_RD_RB_RI
;
3394 if (*input_line_pointer
== '-')
3396 operands
[0].mode
= M68XG_OP_RD_RB_mRI
;
3397 input_line_pointer
++;
3399 operands
[2].reg1
= register_name ();
3400 if (operands
[2].reg1
== REG_NONE
)
3402 as_bad ("Invalid register\n");
3406 if (*input_line_pointer
== '+')
3408 if (opcode_local
.format
== M68XG_OP_RD_RB_mRI
)
3410 as_bad (_("Illegal operand."));
3413 operands
[0].mode
= M68XG_OP_RD_RB_RIp
;
3414 input_line_pointer
++;
3417 input_line_pointer
= skip_whites (input_line_pointer
);
3418 if (*input_line_pointer
!= ')')
3421 ("Missing `)' to close register indirect operand.");
3426 input_line_pointer
++;
3429 opcode
= find (opc
, operands
, 1);
3432 opcode_local
.opcode
= opcode
->opcode
3433 | (operands
[0].reg1
<< 8) | (operands
[1].reg1
<< 5)
3434 | (operands
[2].reg1
<< 2);
3435 opcode_local
.format
= M68XG_OP_NONE
;
3436 build_insn_xg (&opcode_local
, operands
, 1);
3440 as_bad ("Failed to find opcode for %s %s\n",
3441 opc
->opcode
->name
, (char *)op_end
);
3448 as_bad (_("Failed to find a valid mode for `%s'."),
3452 if (opc
->opcode
&& !flag_mri
)
3454 char *p
= input_line_pointer
;
3456 while (*p
== ' ' || *p
== '\t' || *p
== '\n' || *p
== '\r')
3459 if (*p
!= '\n' && *p
)
3460 as_bad (_("Garbage at end of instruction: `%s'."), p
);
3463 input_line_pointer
= save
;
3465 /* Opcode is known but does not have valid operands. Print out the
3466 syntax for this opcode. */
3467 if (opc
->opcode
== 0)
3469 if (flag_print_insn_syntax
)
3470 print_insn_format (name
);
3472 as_bad (_("Invalid operand for `%s'"), name
);
3479 /* Find the opcode definition given its name. */
3480 opc
= (struct m68hc11_opcode_def
*) hash_find (m68hc11_hash
, name
);
3482 /* If it's not recognized, look for 'jbsr' and 'jbxx'. These are
3483 pseudo insns for relative branch. For these branches, we always
3484 optimize them (turned into absolute branches) even if --short-branches
3486 if (opc
== NULL
&& name
[0] == 'j' && name
[1] == 'b')
3488 opc
= (struct m68hc11_opcode_def
*) hash_find (m68hc11_hash
, &name
[1]);
3490 && (!(opc
->format
& M6811_OP_JUMP_REL
)
3491 || (opc
->format
& M6811_OP_BITMASK
)))
3494 branch_optimize
= 1;
3497 /* The following test should probably be removed. This does not conform
3498 to Motorola assembler specs. */
3499 if (opc
== NULL
&& flag_mri
)
3501 if (*op_end
== ' ' || *op_end
== '\t')
3503 while (*op_end
== ' ' || *op_end
== '\t')
3508 (is_end_of_line
[op_end
[1]]
3509 || op_end
[1] == ' ' || op_end
[1] == '\t'
3510 || !ISALNUM (op_end
[1])))
3511 && (*op_end
== 'a' || *op_end
== 'b'
3512 || *op_end
== 'A' || *op_end
== 'B'
3513 || *op_end
== 'd' || *op_end
== 'D'
3514 || *op_end
== 'x' || *op_end
== 'X'
3515 || *op_end
== 'y' || *op_end
== 'Y'))
3517 name
[nlen
++] = TOLOWER (*op_end
++);
3519 opc
= (struct m68hc11_opcode_def
*) hash_find (m68hc11_hash
,
3525 /* Identify a possible instruction alias. There are some on the
3526 68HC12 to emulate a few 68HC11 instructions. */
3527 if (opc
== NULL
&& (current_architecture
& cpu6812
))
3531 for (i
= 0; i
< m68hc12_num_alias
; i
++)
3532 if (strcmp (m68hc12_alias
[i
].name
, name
) == 0)
3538 if (opc
== NULL
&& alias_id
< 0)
3540 as_bad (_("Opcode `%s' is not recognized."), name
);
3543 save
= input_line_pointer
;
3544 input_line_pointer
= (char *) op_end
;
3549 opcode
= find_opcode (opc
, operands
, &nb_operands
);
3554 if ((opcode
|| alias_id
>= 0) && !flag_mri
)
3556 char *p
= input_line_pointer
;
3558 while (*p
== ' ' || *p
== '\t' || *p
== '\n' || *p
== '\r')
3561 if (*p
!= '\n' && *p
)
3562 as_bad (_("Garbage at end of instruction: `%s'."), p
);
3565 input_line_pointer
= save
;
3569 char *f
= m68hc11_new_insn (m68hc12_alias
[alias_id
].size
);
3571 number_to_chars_bigendian (f
, m68hc12_alias
[alias_id
].code1
, 1);
3572 if (m68hc12_alias
[alias_id
].size
> 1)
3573 number_to_chars_bigendian (f
+ 1, m68hc12_alias
[alias_id
].code2
, 1);
3578 /* Opcode is known but does not have valid operands. Print out the
3579 syntax for this opcode. */
3582 if (flag_print_insn_syntax
)
3583 print_insn_format (name
);
3585 if (((strcmp (name
, "movb") == 0) || (strcmp (name
, "movw") == 0))
3586 && (current_architecture
& cpu9s12x
))
3590 if (strcmp (name
, "movb") == 0)
3595 /* The existing operand extract code fell over if these additional modes
3596 were enabled in m68hc11-opc.c. So they are commented there and
3597 decoded here instead. */
3599 if (operands
[1].mode
& (M6812_OP_IDX
| M6812_OP_IDX_1
3600 | M6812_OP_IDX_2
| M6812_OP_D_IDX
| M6812_OP_D_IDX_2
| M6812_PRE_INC
3601 | M6812_PRE_DEC
| M6812_POST_INC
| M6812_POST_DEC
))
3603 /* first check if valid mode then start building it up */
3604 if (operands
[0].mode
& (M6811_OP_IMM8
| M6811_OP_IMM16
3605 | M6811_OP_IND16
| M6812_OP_IDX
| M6812_OP_IDX_1
3606 | M6812_OP_IDX_2
| M6812_OP_D_IDX
| M6812_OP_D_IDX_2
))
3609 if (operands
[1].mode
& (M6811_OP_IND16
))
3614 f
= m68hc11_new_insn (2);
3616 if (operands
[0].mode
& (M6811_OP_IMM8
| M6811_OP_IMM16
))
3618 number_to_chars_bigendian (f
, 0x1800 + movb
+ opr16a
, 2);
3619 build_indexed_byte (&operands
[1], operands
[1].mode
, 1);
3621 fixup8 (&operands
[0].exp
, M6811_OP_IMM8
,
3624 fixup16 (&operands
[0].exp
, M6811_OP_IMM16
,
3629 else if (operands
[0].mode
& M6811_OP_IND16
)
3631 number_to_chars_bigendian (f
, 0x1801 + movb
+ opr16a
, 2);
3632 build_indexed_byte (&operands
[1], operands
[1].mode
, 1);
3633 fixup16 (&operands
[0].exp
, M6811_OP_IND16
, operands
[0].mode
);
3638 number_to_chars_bigendian (f
, 0x1802 + movb
+ opr16a
, 2);
3639 build_indexed_byte (&operands
[0], operands
[0].mode
, 1);
3640 build_indexed_byte (&operands
[1], operands
[1].mode
, 1);
3645 else if (operands
[1].mode
& M6811_OP_IND16
)
3647 /* First check if this is valid mode, then start building it up. */
3648 if (operands
[0].mode
& (M6811_OP_IMM8
| M6811_OP_IMM16
3649 | M6811_OP_IND16
| M6812_OP_IDX
| M6812_OP_IDX_1
3650 | M6812_OP_IDX_2
| M6812_OP_D_IDX
| M6812_OP_D_IDX_2
))
3653 if (operands
[1].mode
& (M6811_OP_IND16
))
3658 f
= m68hc11_new_insn (2);
3660 /* The first two cases here should actually be covered by the
3661 normal operand code. */
3662 if (operands
[0].mode
& (M6811_OP_IMM8
| M6811_OP_IMM16
))
3664 number_to_chars_bigendian (f
, 0x1800 + movb
+ opr16a
, 2);
3666 fixup8 (&operands
[0].exp
, M6811_OP_IMM8
, operands
[0].mode
);
3668 fixup16 (&operands
[0].exp
, M6811_OP_IMM16
, operands
[0].mode
);
3670 fixup16 (&operands
[0].exp
, M6811_OP_IND16
, operands
[0].mode
);
3673 else if (operands
[0].mode
& M6811_OP_IND16
)
3675 number_to_chars_bigendian (f
, 0x1801 + movb
+ opr16a
, 2);
3676 build_indexed_byte (&operands
[1], operands
[1].mode
, 1);
3677 fixup16 (&operands
[0].exp
, M6811_OP_IND16
, operands
[0].mode
);
3682 number_to_chars_bigendian (f
, 0x1802 + movb
+ opr16a
, 2);
3683 build_indexed_byte (&operands
[0], operands
[0].mode
, 1);
3684 fixup16 (&operands
[1].exp
, M6811_OP_IND16
, operands
[1].mode
);
3690 as_bad (_("Invalid operand for `%s'"), name
);
3696 as_bad (_("Invalid operand for `%s'"), name
);
3701 /* Treat dbeq/ibeq/tbeq instructions in a special way. The branch is
3702 relative and must be in the range -256..255 (9-bits). */
3703 if ((opcode
->format
& M6812_XBCC_MARKER
)
3704 && (opcode
->format
& M6811_OP_JUMP_REL
))
3705 build_dbranch_insn (opcode
, operands
, nb_operands
, branch_optimize
);
3707 /* Relative jumps instructions are taken care of separately. We have to make
3708 sure that the relative branch is within the range -128..127. If it's out
3709 of range, the instructions are changed into absolute instructions.
3710 This is not supported for the brset and brclr instructions. */
3711 else if ((opcode
->format
& (M6811_OP_JUMP_REL
| M6812_OP_JUMP_REL16
))
3712 && !(opcode
->format
& M6811_OP_BITMASK
))
3713 build_jump_insn (opcode
, operands
, nb_operands
, branch_optimize
);
3715 build_insn (opcode
, operands
, nb_operands
);
3719 /* Pseudo op to control the ELF flags. */
3721 s_m68hc11_mode (int x ATTRIBUTE_UNUSED
)
3723 char *name
= input_line_pointer
, ch
;
3725 while (!is_end_of_line
[(unsigned char) *input_line_pointer
])
3726 input_line_pointer
++;
3727 ch
= *input_line_pointer
;
3728 *input_line_pointer
= '\0';
3730 if (strcmp (name
, "mshort") == 0)
3732 elf_flags
&= ~E_M68HC11_I32
;
3734 else if (strcmp (name
, "mlong") == 0)
3736 elf_flags
|= E_M68HC11_I32
;
3738 else if (strcmp (name
, "mshort-double") == 0)
3740 elf_flags
&= ~E_M68HC11_F64
;
3742 else if (strcmp (name
, "mlong-double") == 0)
3744 elf_flags
|= E_M68HC11_F64
;
3748 as_warn (_("Invalid mode: %s\n"), name
);
3750 *input_line_pointer
= ch
;
3751 demand_empty_rest_of_line ();
3754 /* Mark the symbols with STO_M68HC12_FAR to indicate the functions
3755 are using 'rtc' for returning. It is necessary to use 'call'
3756 to invoke them. This is also used by the debugger to correctly
3757 find the stack frame. */
3759 s_m68hc11_mark_symbol (int mark
)
3765 elf_symbol_type
*elfsym
;
3769 name
= input_line_pointer
;
3770 c
= get_symbol_end ();
3771 symbolP
= symbol_find_or_make (name
);
3772 *input_line_pointer
= c
;
3776 bfdsym
= symbol_get_bfdsym (symbolP
);
3777 elfsym
= elf_symbol_from (bfd_asymbol_bfd (bfdsym
), bfdsym
);
3779 gas_assert (elfsym
);
3781 /* Mark the symbol far (using rtc for function return). */
3782 elfsym
->internal_elf_sym
.st_other
|= mark
;
3786 input_line_pointer
++;
3790 if (*input_line_pointer
== '\n')
3796 demand_empty_rest_of_line ();
3800 s_m68hc11_relax (int ignore ATTRIBUTE_UNUSED
)
3806 if (ex
.X_op
!= O_symbol
|| ex
.X_add_number
!= 0)
3808 as_bad (_("bad .relax format"));
3809 ignore_rest_of_line ();
3813 fix_new_exp (frag_now
, frag_now_fix (), 0, &ex
, 1,
3814 BFD_RELOC_M68HC11_RL_GROUP
);
3816 demand_empty_rest_of_line ();
3820 /* Relocation, relaxation and frag conversions. */
3822 /* PC-relative offsets are relative to the start of the
3823 next instruction. That is, the address of the offset, plus its
3824 size, since the offset is always the last part of the insn. */
3826 md_pcrel_from (fixS
*fixP
)
3828 if (fixP
->fx_r_type
== BFD_RELOC_M68HC11_RL_JUMP
)
3831 return fixP
->fx_size
+ fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
3834 /* If while processing a fixup, a reloc really needs to be created
3835 then it is done here. */
3837 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
, fixS
*fixp
)
3841 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
3842 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
3843 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
3844 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
3845 if (fixp
->fx_r_type
== 0)
3846 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_16
);
3848 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
3849 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
3851 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
3852 _("Relocation %d is not supported by object file format."),
3853 (int) fixp
->fx_r_type
);
3857 /* Since we use Rel instead of Rela, encode the vtable entry to be
3858 used in the relocation's section offset. */
3859 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
3860 reloc
->address
= fixp
->fx_offset
;
3866 /* We need a port-specific relaxation function to cope with sym2 - sym1
3867 relative expressions with both symbols in the same segment (but not
3868 necessarily in the same frag as this insn), for example:
3869 ldab sym2-(sym1-2),pc
3871 The offset can be 5, 9 or 16 bits long. */
3874 m68hc11_relax_frag (segT seg ATTRIBUTE_UNUSED
, fragS
*fragP
,
3875 long stretch ATTRIBUTE_UNUSED
)
3880 const relax_typeS
*this_type
;
3881 const relax_typeS
*start_type
;
3882 relax_substateT next_state
;
3883 relax_substateT this_state
;
3884 const relax_typeS
*table
= TC_GENERIC_RELAX_TABLE
;
3886 /* We only have to cope with frags as prepared by
3887 md_estimate_size_before_relax. The STATE_BITS16 case may geet here
3888 because of the different reasons that it's not relaxable. */
3889 switch (fragP
->fr_subtype
)
3891 case ENCODE_RELAX (STATE_INDEXED_PCREL
, STATE_BITS16
):
3892 case ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS16
):
3893 /* When we get to this state, the frag won't grow any more. */
3896 case ENCODE_RELAX (STATE_INDEXED_PCREL
, STATE_BITS5
):
3897 case ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS5
):
3898 case ENCODE_RELAX (STATE_INDEXED_PCREL
, STATE_BITS9
):
3899 case ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS9
):
3900 if (fragP
->fr_symbol
== NULL
3901 || S_GET_SEGMENT (fragP
->fr_symbol
) != absolute_section
)
3902 as_fatal (_("internal inconsistency problem in %s: fr_symbol %lx"),
3903 __FUNCTION__
, (long) fragP
->fr_symbol
);
3904 symbolP
= fragP
->fr_symbol
;
3905 if (symbol_resolved_p (symbolP
))
3906 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
3908 aim
= S_GET_VALUE (symbolP
);
3912 as_fatal (_("internal inconsistency problem in %s: fr_subtype %d"),
3913 __FUNCTION__
, fragP
->fr_subtype
);
3916 /* The rest is stolen from relax_frag. There's no obvious way to
3917 share the code, but fortunately no requirement to keep in sync as
3918 long as fragP->fr_symbol does not have its segment changed. */
3920 this_state
= fragP
->fr_subtype
;
3921 start_type
= this_type
= table
+ this_state
;
3925 /* Look backwards. */
3926 for (next_state
= this_type
->rlx_more
; next_state
;)
3927 if (aim
>= this_type
->rlx_backward
)
3931 /* Grow to next state. */
3932 this_state
= next_state
;
3933 this_type
= table
+ this_state
;
3934 next_state
= this_type
->rlx_more
;
3939 /* Look forwards. */
3940 for (next_state
= this_type
->rlx_more
; next_state
;)
3941 if (aim
<= this_type
->rlx_forward
)
3945 /* Grow to next state. */
3946 this_state
= next_state
;
3947 this_type
= table
+ this_state
;
3948 next_state
= this_type
->rlx_more
;
3952 growth
= this_type
->rlx_length
- start_type
->rlx_length
;
3954 fragP
->fr_subtype
= this_state
;
3959 md_convert_frag (bfd
*abfd ATTRIBUTE_UNUSED
, asection
*sec ATTRIBUTE_UNUSED
,
3965 char *buffer_address
= fragP
->fr_literal
;
3967 /* Address in object code of the displacement. */
3968 register int object_address
= fragP
->fr_fix
+ fragP
->fr_address
;
3970 buffer_address
+= fragP
->fr_fix
;
3972 /* The displacement of the address, from current location. */
3973 value
= S_GET_VALUE (fragP
->fr_symbol
);
3974 disp
= (value
+ fragP
->fr_offset
) - object_address
;
3976 switch (fragP
->fr_subtype
)
3978 case ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_BYTE
):
3979 fragP
->fr_opcode
[1] = disp
;
3982 case ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_WORD
):
3983 /* This relax is only for bsr and bra. */
3984 gas_assert (IS_OPCODE (fragP
->fr_opcode
[0], M6811_BSR
)
3985 || IS_OPCODE (fragP
->fr_opcode
[0], M6811_BRA
)
3986 || IS_OPCODE (fragP
->fr_opcode
[0], M6812_BSR
));
3988 fragP
->fr_opcode
[0] = convert_branch (fragP
->fr_opcode
[0]);
3990 fix_new (fragP
, fragP
->fr_fix
- 1, 2,
3991 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_16
);
3995 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
, STATE_BYTE
):
3996 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
, STATE_BYTE
):
3997 fragP
->fr_opcode
[1] = disp
;
4000 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
, STATE_WORD
):
4001 /* Invert branch. */
4002 fragP
->fr_opcode
[0] ^= 1;
4003 fragP
->fr_opcode
[1] = 3; /* Branch offset. */
4004 buffer_address
[0] = M6811_JMP
;
4005 fix_new (fragP
, fragP
->fr_fix
+ 1, 2,
4006 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_16
);
4010 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
, STATE_WORD
):
4011 /* Translate branch into a long branch. */
4012 fragP
->fr_opcode
[1] = fragP
->fr_opcode
[0];
4013 fragP
->fr_opcode
[0] = M6811_OPCODE_PAGE2
;
4015 fixp
= fix_new (fragP
, fragP
->fr_fix
, 2,
4016 fragP
->fr_symbol
, fragP
->fr_offset
, 1,
4017 BFD_RELOC_16_PCREL
);
4018 fixp
->fx_pcrel_adjust
= 2;
4022 case ENCODE_RELAX (STATE_INDEXED_PCREL
, STATE_BITS5
):
4023 if (fragP
->fr_symbol
!= 0
4024 && S_GET_SEGMENT (fragP
->fr_symbol
) != absolute_section
)
4028 case ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS5
):
4029 fragP
->fr_opcode
[0] = fragP
->fr_opcode
[0] << 6;
4030 fragP
->fr_opcode
[0] |= value
& 0x1f;
4033 case ENCODE_RELAX (STATE_INDEXED_PCREL
, STATE_BITS9
):
4034 /* For a PC-relative offset, use the displacement with a -1 correction
4035 to take into account the additional byte of the insn. */
4036 if (fragP
->fr_symbol
!= 0
4037 && S_GET_SEGMENT (fragP
->fr_symbol
) != absolute_section
)
4041 case ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS9
):
4042 fragP
->fr_opcode
[0] = (fragP
->fr_opcode
[0] << 3);
4043 fragP
->fr_opcode
[0] |= 0xE0;
4044 fragP
->fr_opcode
[0] |= (value
>> 8) & 1;
4045 fragP
->fr_opcode
[1] = value
;
4049 case ENCODE_RELAX (STATE_INDEXED_PCREL
, STATE_BITS16
):
4050 case ENCODE_RELAX (STATE_INDEXED_OFFSET
, STATE_BITS16
):
4051 fragP
->fr_opcode
[0] = (fragP
->fr_opcode
[0] << 3);
4052 fragP
->fr_opcode
[0] |= 0xe2;
4053 if ((fragP
->fr_opcode
[0] & 0x0ff) == 0x0fa
4054 && fragP
->fr_symbol
!= 0
4055 && S_GET_SEGMENT (fragP
->fr_symbol
) != absolute_section
)
4057 fixp
= fix_new (fragP
, fragP
->fr_fix
, 2,
4058 fragP
->fr_symbol
, fragP
->fr_offset
,
4059 1, BFD_RELOC_16_PCREL
);
4063 fix_new (fragP
, fragP
->fr_fix
, 2,
4064 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_16
);
4069 case ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_BYTE
):
4071 fragP
->fr_opcode
[0] |= 0x10;
4073 fragP
->fr_opcode
[1] = disp
& 0x0FF;
4076 case ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_WORD
):
4077 /* Invert branch. */
4078 fragP
->fr_opcode
[0] ^= 0x20;
4079 fragP
->fr_opcode
[1] = 3; /* Branch offset. */
4080 buffer_address
[0] = M6812_JMP
;
4081 fix_new (fragP
, fragP
->fr_fix
+ 1, 2,
4082 fragP
->fr_symbol
, fragP
->fr_offset
, 0, BFD_RELOC_16
);
4091 /* On an ELF system, we can't relax a weak symbol. The weak symbol
4092 can be overridden at final link time by a non weak symbol. We can
4093 relax externally visible symbol because there is no shared library
4094 and such symbol can't be overridden (unless they are weak). */
4096 relaxable_symbol (symbolS
*symbol
)
4098 return ! S_IS_WEAK (symbol
);
4101 /* Force truly undefined symbols to their maximum size, and generally set up
4102 the frag list to be relaxed. */
4104 md_estimate_size_before_relax (fragS
*fragP
, asection
*segment
)
4106 if (RELAX_LENGTH (fragP
->fr_subtype
) == STATE_UNDF
)
4108 if (S_GET_SEGMENT (fragP
->fr_symbol
) != segment
4109 || !relaxable_symbol (fragP
->fr_symbol
)
4110 || (segment
!= absolute_section
4111 && RELAX_STATE (fragP
->fr_subtype
) == STATE_INDEXED_OFFSET
))
4113 /* Non-relaxable cases. */
4115 char *buffer_address
;
4117 old_fr_fix
= fragP
->fr_fix
;
4118 buffer_address
= fragP
->fr_fix
+ fragP
->fr_literal
;
4120 switch (RELAX_STATE (fragP
->fr_subtype
))
4122 case STATE_PC_RELATIVE
:
4124 /* This relax is only for bsr and bra. */
4125 gas_assert (IS_OPCODE (fragP
->fr_opcode
[0], M6811_BSR
)
4126 || IS_OPCODE (fragP
->fr_opcode
[0], M6811_BRA
)
4127 || IS_OPCODE (fragP
->fr_opcode
[0], M6812_BSR
));
4129 if (flag_fixed_branches
)
4130 as_bad_where (fragP
->fr_file
, fragP
->fr_line
,
4131 _("bra or bsr with undefined symbol."));
4133 /* The symbol is undefined or in a separate section.
4134 Turn bra into a jmp and bsr into a jsr. The insn
4135 becomes 3 bytes long (instead of 2). A fixup is
4136 necessary for the unresolved symbol address. */
4137 fragP
->fr_opcode
[0] = convert_branch (fragP
->fr_opcode
[0]);
4139 fix_new (fragP
, fragP
->fr_fix
- 1, 2, fragP
->fr_symbol
,
4140 fragP
->fr_offset
, 0, BFD_RELOC_16
);
4144 case STATE_CONDITIONAL_BRANCH
:
4145 gas_assert (current_architecture
& cpu6811
);
4147 fragP
->fr_opcode
[0] ^= 1; /* Reverse sense of branch. */
4148 fragP
->fr_opcode
[1] = 3; /* Skip next jmp insn (3 bytes). */
4150 /* Don't use fr_opcode[2] because this may be
4151 in a different frag. */
4152 buffer_address
[0] = M6811_JMP
;
4155 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
4156 fragP
->fr_offset
, 0, BFD_RELOC_16
);
4160 case STATE_INDEXED_OFFSET
:
4161 gas_assert (current_architecture
& cpu6812
);
4163 if (fragP
->fr_symbol
4164 && S_GET_SEGMENT (fragP
->fr_symbol
) == absolute_section
)
4166 fragP
->fr_subtype
= ENCODE_RELAX (STATE_INDEXED_OFFSET
,
4168 /* Return the size of the variable part of the frag. */
4169 return md_relax_table
[fragP
->fr_subtype
].rlx_length
;
4173 /* Switch the indexed operation to 16-bit mode. */
4174 fragP
->fr_opcode
[0] = fragP
->fr_opcode
[0] << 3;
4175 fragP
->fr_opcode
[0] |= 0xe2;
4176 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
4177 fragP
->fr_offset
, 0, BFD_RELOC_16
);
4182 case STATE_INDEXED_PCREL
:
4183 gas_assert (current_architecture
& cpu6812
);
4185 if (fragP
->fr_symbol
4186 && S_GET_SEGMENT (fragP
->fr_symbol
) == absolute_section
)
4188 fragP
->fr_subtype
= ENCODE_RELAX (STATE_INDEXED_PCREL
,
4190 /* Return the size of the variable part of the frag. */
4191 return md_relax_table
[fragP
->fr_subtype
].rlx_length
;
4195 fragP
->fr_opcode
[0] = fragP
->fr_opcode
[0] << 3;
4196 fragP
->fr_opcode
[0] |= 0xe2;
4197 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
4198 fragP
->fr_offset
, 1, BFD_RELOC_16_PCREL
);
4203 case STATE_XBCC_BRANCH
:
4204 gas_assert (current_architecture
& cpu6812
);
4206 fragP
->fr_opcode
[0] ^= 0x20; /* Reverse sense of branch. */
4207 fragP
->fr_opcode
[1] = 3; /* Skip next jmp insn (3 bytes). */
4209 /* Don't use fr_opcode[2] because this may be
4210 in a different frag. */
4211 buffer_address
[0] = M6812_JMP
;
4214 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
4215 fragP
->fr_offset
, 0, BFD_RELOC_16
);
4219 case STATE_CONDITIONAL_BRANCH_6812
:
4220 gas_assert (current_architecture
& cpu6812
);
4222 /* Translate into a lbcc branch. */
4223 fragP
->fr_opcode
[1] = fragP
->fr_opcode
[0];
4224 fragP
->fr_opcode
[0] = M6811_OPCODE_PAGE2
;
4226 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
4227 fragP
->fr_offset
, 1, BFD_RELOC_16_PCREL
);
4232 as_fatal (_("Subtype %d is not recognized."), fragP
->fr_subtype
);
4236 /* Return the growth in the fixed part of the frag. */
4237 return fragP
->fr_fix
- old_fr_fix
;
4240 /* Relaxable cases. */
4241 switch (RELAX_STATE (fragP
->fr_subtype
))
4243 case STATE_PC_RELATIVE
:
4244 /* This relax is only for bsr and bra. */
4245 gas_assert (IS_OPCODE (fragP
->fr_opcode
[0], M6811_BSR
)
4246 || IS_OPCODE (fragP
->fr_opcode
[0], M6811_BRA
)
4247 || IS_OPCODE (fragP
->fr_opcode
[0], M6812_BSR
));
4249 fragP
->fr_subtype
= ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_BYTE
);
4252 case STATE_CONDITIONAL_BRANCH
:
4253 gas_assert (current_architecture
& cpu6811
);
4255 fragP
->fr_subtype
= ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
,
4259 case STATE_INDEXED_OFFSET
:
4260 gas_assert (current_architecture
& cpu6812
);
4262 fragP
->fr_subtype
= ENCODE_RELAX (STATE_INDEXED_OFFSET
,
4266 case STATE_INDEXED_PCREL
:
4267 gas_assert (current_architecture
& cpu6812
);
4269 fragP
->fr_subtype
= ENCODE_RELAX (STATE_INDEXED_PCREL
,
4273 case STATE_XBCC_BRANCH
:
4274 gas_assert (current_architecture
& cpu6812
);
4276 fragP
->fr_subtype
= ENCODE_RELAX (STATE_XBCC_BRANCH
, STATE_BYTE
);
4279 case STATE_CONDITIONAL_BRANCH_6812
:
4280 gas_assert (current_architecture
& cpu6812
);
4282 fragP
->fr_subtype
= ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812
,
4288 if (fragP
->fr_subtype
>= sizeof (md_relax_table
) / sizeof (md_relax_table
[0]))
4289 as_fatal (_("Subtype %d is not recognized."), fragP
->fr_subtype
);
4291 /* Return the size of the variable part of the frag. */
4292 return md_relax_table
[fragP
->fr_subtype
].rlx_length
;
4295 /* See whether we need to force a relocation into the output file. */
4297 tc_m68hc11_force_relocation (fixS
*fixP
)
4299 if (fixP
->fx_r_type
== BFD_RELOC_M68HC11_RL_GROUP
)
4302 return generic_force_reloc (fixP
);
4305 /* Here we decide which fixups can be adjusted to make them relative
4306 to the beginning of the section instead of the symbol. Basically
4307 we need to make sure that the linker relaxation is done
4308 correctly, so in some cases we force the original symbol to be
4311 tc_m68hc11_fix_adjustable (fixS
*fixP
)
4313 switch (fixP
->fx_r_type
)
4315 /* For the linker relaxation to work correctly, these relocs
4316 need to be on the symbol itself. */
4318 case BFD_RELOC_M68HC11_RL_JUMP
:
4319 case BFD_RELOC_M68HC11_RL_GROUP
:
4320 case BFD_RELOC_VTABLE_INHERIT
:
4321 case BFD_RELOC_VTABLE_ENTRY
:
4324 /* The memory bank addressing translation also needs the original
4326 case BFD_RELOC_M68HC11_LO16
:
4327 case BFD_RELOC_M68HC11_PAGE
:
4328 case BFD_RELOC_M68HC11_24
:
4337 md_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg ATTRIBUTE_UNUSED
)
4340 long value
= * valP
;
4342 if (fixP
->fx_addsy
== (symbolS
*) NULL
)
4345 /* We don't actually support subtracting a symbol. */
4346 if (fixP
->fx_subsy
!= (symbolS
*) NULL
)
4347 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("Expression too complex."));
4349 /* Patch the instruction with the resolved operand. Elf relocation
4350 info will also be generated to take care of linker/loader fixups.
4351 The 68HC11 addresses only 64Kb, we are only concerned by 8 and 16-bit
4352 relocs. BFD_RELOC_8 is basically used for .page0 access (the linker
4353 will warn for overflows). BFD_RELOC_8_PCREL should not be generated
4354 because it's either resolved or turned out into non-relative insns (see
4355 relax table, bcc, bra, bsr transformations)
4357 The BFD_RELOC_32 is necessary for the support of --gstabs. */
4358 where
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
4360 switch (fixP
->fx_r_type
)
4363 bfd_putb32 ((bfd_vma
) value
, (unsigned char *) where
);
4367 case BFD_RELOC_M68HC11_24
:
4368 bfd_putb16 ((bfd_vma
) (value
& 0x0ffff), (unsigned char *) where
);
4369 ((bfd_byte
*) where
)[2] = ((value
>> 16) & 0x0ff);
4373 case BFD_RELOC_16_PCREL
:
4374 case BFD_RELOC_M68HC11_LO16
:
4375 bfd_putb16 ((bfd_vma
) value
, (unsigned char *) where
);
4376 if (value
< -65537 || value
> 65535)
4377 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
4378 _("Value out of 16-bit range."));
4381 case BFD_RELOC_M68HC11_HI8
:
4382 /* Caution, %hi(<symbol>+%ld) will generate incorrect code if %lo
4384 case BFD_RELOC_M68HC12_HI8XG
:
4388 case BFD_RELOC_M68HC12_LO8XG
:
4389 case BFD_RELOC_M68HC11_LO8
:
4391 case BFD_RELOC_M68HC11_PAGE
:
4392 ((bfd_byte
*) where
)[0] = (bfd_byte
) value
;
4395 case BFD_RELOC_8_PCREL
:
4396 ((bfd_byte
*) where
)[0] = (bfd_byte
) value
;
4398 if (value
< -128 || value
> 127)
4399 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
4400 _("Value %ld too large for 8-bit PC-relative branch."),
4404 /* These next two are for XGATE. */
4405 case BFD_RELOC_M68HC12_9_PCREL
:
4406 ((bfd_byte
*) where
)[0] |= (bfd_byte
) ((value
>>9) & 0x01);
4407 ((bfd_byte
*) where
)[1] = (bfd_byte
) ((value
>>1) & 0xff);
4408 if (value
< -512 || value
> 511)
4409 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
4410 _("Value %ld too large for 9-bit PC-relative branch."),
4414 case BFD_RELOC_M68HC12_10_PCREL
:
4415 ((bfd_byte
*) where
)[0] |= (bfd_byte
) ((value
>>9) & 0x03);
4416 ((bfd_byte
*) where
)[1] = (bfd_byte
) ((value
>>1) & 0xff);
4417 if (value
< -1024 || value
> 1023)
4418 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
4419 _("Value %ld too large for 10-bit PC-relative branch."),
4424 case BFD_RELOC_M68HC11_3B
:
4425 if (value
<= 0 || value
> 8)
4426 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
4427 _("Auto increment/decrement offset '%ld' is out of range."),
4434 where
[0] = where
[0] | (value
& 0x07);
4437 case BFD_RELOC_M68HC12_5B
:
4438 if (value
< -16 || value
> 15)
4439 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
4440 _("Offset out of 5-bit range for movw/movb insn: %ld"),
4445 where
[0] |= (0x10 | (16 + value
));
4448 case BFD_RELOC_M68HC12_9B
:
4449 if (value
< -256 || value
> 255)
4450 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
4451 _("Offset out of 9-bit range for movw/movb insn: %ld"),
4453 /* sign bit already in xb postbyte */
4457 where
[1] = (256 + value
);
4460 case BFD_RELOC_M68HC12_16B
:
4461 if (value
< -32768 || value
> 32767)
4462 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
4463 _("Offset out of 16-bit range for movw/movb insn: %ld"),
4468 where
[1] = (value
>> 8);
4469 where
[2] = (value
& 0xff);
4472 case BFD_RELOC_M68HC11_RL_JUMP
:
4473 case BFD_RELOC_M68HC11_RL_GROUP
:
4474 case BFD_RELOC_VTABLE_INHERIT
:
4475 case BFD_RELOC_VTABLE_ENTRY
:
4480 as_fatal (_("Line %d: unknown relocation type: 0x%x."),
4481 fixP
->fx_line
, fixP
->fx_r_type
);
4485 /* Set the ELF specific flags. */
4487 m68hc11_elf_final_processing (void)
4489 if (current_architecture
& cpu6812s
)
4490 elf_flags
|= EF_M68HCS12_MACH
;
4491 elf_elfheader (stdoutput
)->e_flags
&= ~EF_M68HC11_ABI
;
4492 elf_elfheader (stdoutput
)->e_flags
|= elf_flags
;