]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gas/config/tc-m68hc11.c
* dlltool.c: Warning fixes.
[thirdparty/binutils-gdb.git] / gas / config / tc-m68hc11.c
CommitLineData
60bcf0fa 1/* tc-m68hc11.c -- Assembler code for the Motorola 68HC11 & 68HC12.
28d39d1a 2 Copyright 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
7bfda7eb 3 Written by Stephane Carrez (stcarrez@nerim.fr)
60bcf0fa
NC
4
5 This file is part of GAS, the GNU Assembler.
6
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
21
60bcf0fa 22#include "as.h"
3882b010 23#include "safe-ctype.h"
60bcf0fa
NC
24#include "subsegs.h"
25#include "opcode/m68hc11.h"
26#include "dwarf2dbg.h"
7bfda7eb 27#include "elf/m68hc11.h"
60bcf0fa 28
60bcf0fa
NC
29const char comment_chars[] = ";!";
30const char line_comment_chars[] = "#*";
31const char line_separator_chars[] = "";
32
33const char EXP_CHARS[] = "eE";
34const char FLT_CHARS[] = "dD";
35
36#define STATE_CONDITIONAL_BRANCH (1)
37#define STATE_PC_RELATIVE (2)
38#define STATE_INDEXED_OFFSET (3)
75538612
SC
39#define STATE_INDEXED_PCREL (4)
40#define STATE_XBCC_BRANCH (5)
41#define STATE_CONDITIONAL_BRANCH_6812 (6)
60bcf0fa
NC
42
43#define STATE_BYTE (0)
44#define STATE_BITS5 (0)
45#define STATE_WORD (1)
46#define STATE_BITS9 (1)
47#define STATE_LONG (2)
48#define STATE_BITS16 (2)
49#define STATE_UNDF (3) /* Symbol undefined in pass1 */
50
51/* This macro has no side-effects. */
52#define ENCODE_RELAX(what,length) (((what) << 2) + (length))
606ab118
AM
53#define RELAX_STATE(s) ((s) >> 2)
54#define RELAX_LENGTH(s) ((s) & 3)
60bcf0fa
NC
55
56#define IS_OPCODE(C1,C2) (((C1) & 0x0FF) == ((C2) & 0x0FF))
57
58/* This table describes how you change sizes for the various types of variable
59 size expressions. This version only supports two kinds. */
60
61/* The fields are:
fafb6d17
NC
62 How far Forward this mode will reach.
63 How far Backward this mode will reach.
64 How many bytes this mode will add to the size of the frag.
65 Which mode to go to if the offset won't fit in this one. */
66
098f2ec3 67relax_typeS md_relax_table[] = {
fafb6d17
NC
68 {1, 1, 0, 0}, /* First entries aren't used. */
69 {1, 1, 0, 0}, /* For no good reason except. */
70 {1, 1, 0, 0}, /* that the VAX doesn't either. */
60bcf0fa
NC
71 {1, 1, 0, 0},
72
73 /* Relax for bcc <L>.
74 These insns are translated into b!cc +3 jmp L. */
75 {(127), (-128), 0, ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_WORD)},
76 {0, 0, 3, 0},
77 {1, 1, 0, 0},
78 {1, 1, 0, 0},
79
80 /* Relax for bsr <L> and bra <L>.
81 These insns are translated into jsr and jmp. */
82 {(127), (-128), 0, ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD)},
83 {0, 0, 1, 0},
84 {1, 1, 0, 0},
85 {1, 1, 0, 0},
86
87 /* Relax for indexed offset: 5-bits, 9-bits, 16-bits. */
88 {(15), (-16), 0, ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9)},
89 {(255), (-256), 1, ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16)},
88051039 90 {0, 0, 2, 0},
60bcf0fa
NC
91 {1, 1, 0, 0},
92
75538612
SC
93 /* Relax for PC relative offset: 5-bits, 9-bits, 16-bits.
94 For the 9-bit case, there will be a -1 correction to take into
95 account the new byte that's why the range is -255..256. */
96 {(15), (-16), 0, ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS9)},
97 {(256), (-255), 1, ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS16)},
98 {0, 0, 2, 0},
99 {1, 1, 0, 0},
100
60bcf0fa
NC
101 /* Relax for dbeq/ibeq/tbeq r,<L>:
102 These insns are translated into db!cc +3 jmp L. */
103 {(255), (-256), 0, ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_WORD)},
104 {0, 0, 3, 0},
105 {1, 1, 0, 0},
106 {1, 1, 0, 0},
107
108 /* Relax for bcc <L> on 68HC12.
109 These insns are translated into lbcc <L>. */
110 {(127), (-128), 0, ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_WORD)},
111 {0, 0, 2, 0},
112 {1, 1, 0, 0},
113 {1, 1, 0, 0},
114
115};
116
117/* 68HC11 and 68HC12 registers. They are numbered according to the 68HC12. */
098f2ec3 118typedef enum register_id {
60bcf0fa
NC
119 REG_NONE = -1,
120 REG_A = 0,
121 REG_B = 1,
122 REG_CCR = 2,
123 REG_D = 4,
124 REG_X = 5,
125 REG_Y = 6,
126 REG_SP = 7,
127 REG_PC = 8
128} register_id;
129
098f2ec3 130typedef struct operand {
60bcf0fa
NC
131 expressionS exp;
132 register_id reg1;
133 register_id reg2;
134 int mode;
135} operand;
136
098f2ec3 137struct m68hc11_opcode_def {
60bcf0fa
NC
138 long format;
139 int min_operands;
140 int max_operands;
141 int nb_modes;
142 int used;
143 struct m68hc11_opcode *opcode;
144};
145
146static struct m68hc11_opcode_def *m68hc11_opcode_defs = 0;
147static int m68hc11_nb_opcode_defs = 0;
148
098f2ec3 149typedef struct alias {
60bcf0fa
NC
150 const char *name;
151 const char *alias;
098f2ec3 152} alias;
60bcf0fa 153
098f2ec3 154static alias alias_opcodes[] = {
60bcf0fa
NC
155 {"cpd", "cmpd"},
156 {"cpx", "cmpx"},
157 {"cpy", "cmpy"},
158 {0, 0}
159};
160
fafb6d17 161/* Local functions. */
ca43c854
SC
162static register_id reg_name_search (char *);
163static register_id register_name (void);
164static int cmp_opcode (struct m68hc11_opcode *, struct m68hc11_opcode *);
165static char *print_opcode_format (struct m68hc11_opcode *, int);
166static char *skip_whites (char *);
167static int check_range (long, int);
168static void print_opcode_list (void);
169static void get_default_target (void);
170static void print_insn_format (char *);
171static int get_operand (operand *, int, long);
172static void fixup8 (expressionS *, int, int);
173static void fixup16 (expressionS *, int, int);
174static void fixup24 (expressionS *, int, int);
175static unsigned char convert_branch (unsigned char);
176static char *m68hc11_new_insn (int);
177static void build_dbranch_insn (struct m68hc11_opcode *,
178 operand *, int, int);
179static int build_indexed_byte (operand *, int, int);
180static int build_reg_mode (operand *, int);
181
182static struct m68hc11_opcode *find (struct m68hc11_opcode_def *,
183 operand *, int);
184static struct m68hc11_opcode *find_opcode (struct m68hc11_opcode_def *,
185 operand *, int *);
186static void build_jump_insn (struct m68hc11_opcode *, operand *, int, int);
187static void build_insn (struct m68hc11_opcode *, operand *, int);
188static int relaxable_symbol (symbolS *);
60bcf0fa 189
e371935f 190/* Pseudo op to indicate a relax group. */
ca43c854 191static void s_m68hc11_relax (int);
e371935f 192
eb086b59 193/* Pseudo op to control the ELF flags. */
ca43c854 194static void s_m68hc11_mode (int);
eb086b59
SC
195
196/* Mark the symbols with STO_M68HC12_FAR to indicate the functions
197 are using 'rtc' for returning. It is necessary to use 'call'
198 to invoke them. This is also used by the debugger to correctly
199 find the stack frame. */
ca43c854 200static void s_m68hc11_mark_symbol (int);
eb086b59 201
60bcf0fa
NC
202/* Controls whether relative branches can be turned into long branches.
203 When the relative offset is too large, the insn are changed:
204 bra -> jmp
205 bsr -> jsr
206 bcc -> b!cc +3
207 jmp L
208 dbcc -> db!cc +3
209 jmp L
fafb6d17 210
60bcf0fa
NC
211 Setting the flag forbidds this. */
212static short flag_fixed_branchs = 0;
213
214/* Force to use long jumps (absolute) instead of relative branches. */
215static short flag_force_long_jumps = 0;
216
217/* Change the direct addressing mode into an absolute addressing mode
218 when the insn does not support direct addressing.
219 For example, "clr *ZD0" is normally not possible and is changed
220 into "clr ZDO". */
221static short flag_strict_direct_addressing = 1;
222
223/* When an opcode has invalid operand, print out the syntax of the opcode
224 to stderr. */
225static short flag_print_insn_syntax = 0;
226
227/* Dumps the list of instructions with syntax and then exit:
228 1 -> Only dumps the list (sorted by name)
229 2 -> Generate an example (or test) that can be compiled. */
230static short flag_print_opcodes = 0;
231
232/* Opcode hash table. */
233static struct hash_control *m68hc11_hash;
234
235/* Current cpu (either cpu6811 or cpu6812). This is determined automagically
67c1ffbe 236 by 'get_default_target' by looking at default BFD vector. This is overridden
60bcf0fa
NC
237 with the -m<cpu> option. */
238static int current_architecture = 0;
239
240/* Default cpu determined by 'get_default_target'. */
241static const char *default_cpu;
242
243/* Number of opcodes in the sorted table (filtered by current cpu). */
244static int num_opcodes;
245
246/* The opcodes sorted by name and filtered by current cpu. */
247static struct m68hc11_opcode *m68hc11_sorted_opcodes;
248
eb086b59 249/* ELF flags to set in the output file header. */
2f904664 250static int elf_flags = E_M68HC11_F64;
eb086b59 251
60bcf0fa
NC
252/* These are the machine dependent pseudo-ops. These are included so
253 the assembler can work on the output from the SUN C compiler, which
254 generates these. */
255
256/* This table describes all the machine specific pseudo-ops the assembler
257 has to support. The fields are:
258 pseudo-op name without dot
259 function to call to execute this pseudo-op
260 Integer arg to pass to the function. */
098f2ec3 261const pseudo_typeS md_pseudo_table[] = {
60bcf0fa
NC
262 /* The following pseudo-ops are supported for MRI compatibility. */
263 {"fcb", cons, 1},
264 {"fdb", cons, 2},
265 {"fcc", stringer, 1},
266 {"rmb", s_space, 0},
986c6f4b 267
e629c13f
SC
268 /* Motorola ALIS. */
269 {"xrefb", s_ignore, 0}, /* Same as xref */
270
e371935f
SC
271 /* Gcc driven relaxation. */
272 {"relax", s_m68hc11_relax, 0},
273
eb086b59
SC
274 /* .mode instruction (ala SH). */
275 {"mode", s_m68hc11_mode, 0},
276
277 /* .far instruction. */
278 {"far", s_m68hc11_mark_symbol, STO_M68HC12_FAR},
279
280 /* .interrupt instruction. */
281 {"interrupt", s_m68hc11_mark_symbol, STO_M68HC12_INTERRUPT},
282
60bcf0fa
NC
283 {0, 0, 0}
284};
60bcf0fa
NC
285\f
286/* Options and initialization. */
287
5a38dc70 288const char *md_shortopts = "Sm:";
60bcf0fa 289
098f2ec3 290struct option md_longopts[] = {
60bcf0fa
NC
291#define OPTION_FORCE_LONG_BRANCH (OPTION_MD_BASE)
292 {"force-long-branchs", no_argument, NULL, OPTION_FORCE_LONG_BRANCH},
293
294#define OPTION_SHORT_BRANCHS (OPTION_MD_BASE + 1)
295 {"short-branchs", no_argument, NULL, OPTION_SHORT_BRANCHS},
296
297#define OPTION_STRICT_DIRECT_MODE (OPTION_MD_BASE + 2)
298 {"strict-direct-mode", no_argument, NULL, OPTION_STRICT_DIRECT_MODE},
299
300#define OPTION_PRINT_INSN_SYNTAX (OPTION_MD_BASE + 3)
301 {"print-insn-syntax", no_argument, NULL, OPTION_PRINT_INSN_SYNTAX},
302
303#define OPTION_PRINT_OPCODES (OPTION_MD_BASE + 4)
304 {"print-opcodes", no_argument, NULL, OPTION_PRINT_OPCODES},
305
306#define OPTION_GENERATE_EXAMPLE (OPTION_MD_BASE + 5)
307 {"generate-example", no_argument, NULL, OPTION_GENERATE_EXAMPLE},
308
2f904664
SC
309#define OPTION_MSHORT (OPTION_MD_BASE + 6)
310 {"mshort", no_argument, NULL, OPTION_MSHORT},
311
312#define OPTION_MLONG (OPTION_MD_BASE + 7)
313 {"mlong", no_argument, NULL, OPTION_MLONG},
314
315#define OPTION_MSHORT_DOUBLE (OPTION_MD_BASE + 8)
316 {"mshort-double", no_argument, NULL, OPTION_MSHORT_DOUBLE},
317
318#define OPTION_MLONG_DOUBLE (OPTION_MD_BASE + 9)
319 {"mlong-double", no_argument, NULL, OPTION_MLONG_DOUBLE},
320
60bcf0fa
NC
321 {NULL, no_argument, NULL, 0}
322};
323size_t md_longopts_size = sizeof (md_longopts);
324
325/* Get the target cpu for the assembler. This is based on the configure
326 options and on the -m68hc11/-m68hc12 option. If no option is specified,
327 we must get the default. */
328const char *
ca43c854 329m68hc11_arch_format (void)
60bcf0fa
NC
330{
331 get_default_target ();
332 if (current_architecture & cpu6811)
333 return "elf32-m68hc11";
334 else
335 return "elf32-m68hc12";
336}
337
338enum bfd_architecture
ca43c854 339m68hc11_arch (void)
60bcf0fa
NC
340{
341 get_default_target ();
342 if (current_architecture & cpu6811)
343 return bfd_arch_m68hc11;
344 else
345 return bfd_arch_m68hc12;
346}
347
348int
ca43c854 349m68hc11_mach (void)
60bcf0fa
NC
350{
351 return 0;
352}
353
986c6f4b
SC
354/* Listing header selected according to cpu. */
355const char *
ca43c854 356m68hc11_listing_header (void)
986c6f4b
SC
357{
358 if (current_architecture & cpu6811)
359 return "M68HC11 GAS ";
360 else
361 return "M68HC12 GAS ";
362}
363
60bcf0fa 364void
ca43c854 365md_show_usage (FILE *stream)
60bcf0fa
NC
366{
367 get_default_target ();
368 fprintf (stream, _("\
d01030e6 369Motorola 68HC11/68HC12/68HCS12 options:\n\
f0abc2a1 370 -m68hc11 | -m68hc12 |\n\
d01030e6 371 -m68hcs12 specify the processor [default %s]\n\
2f904664
SC
372 -mshort use 16-bit int ABI (default)\n\
373 -mlong use 32-bit int ABI\n\
374 -mshort-double use 32-bit double ABI\n\
375 -mlong-double use 64-bit double ABI (default)\n\
60bcf0fa
NC
376 --force-long-branchs always turn relative branchs into absolute ones\n\
377 -S,--short-branchs do not turn relative branchs into absolute ones\n\
378 when the offset is out of range\n\
379 --strict-direct-mode do not turn the direct mode into extended mode\n\
380 when the instruction does not support direct mode\n\
381 --print-insn-syntax print the syntax of instruction in case of error\n\
382 --print-opcodes print the list of instructions with syntax\n\
383 --generate-example generate an example of each instruction\n\
384 (used for testing)\n"), default_cpu);
385
386}
387
388/* Try to identify the default target based on the BFD library. */
389static void
ca43c854 390get_default_target (void)
60bcf0fa
NC
391{
392 const bfd_target *target;
393 bfd abfd;
394
395 if (current_architecture != 0)
396 return;
397
398 default_cpu = "unknown";
399 target = bfd_find_target (0, &abfd);
400 if (target && target->name)
401 {
402 if (strcmp (target->name, "elf32-m68hc12") == 0)
403 {
404 current_architecture = cpu6812;
405 default_cpu = "m68hc12";
406 }
407 else if (strcmp (target->name, "elf32-m68hc11") == 0)
408 {
409 current_architecture = cpu6811;
410 default_cpu = "m68hc11";
411 }
412 else
413 {
414 as_bad (_("Default target `%s' is not supported."), target->name);
415 }
416 }
417}
418
419void
ca43c854 420m68hc11_print_statistics (FILE *file)
60bcf0fa
NC
421{
422 int i;
423 struct m68hc11_opcode_def *opc;
424
425 hash_print_statistics (file, "opcode table", m68hc11_hash);
426
427 opc = m68hc11_opcode_defs;
428 if (opc == 0 || m68hc11_nb_opcode_defs == 0)
429 return;
430
431 /* Dump the opcode statistics table. */
432 fprintf (file, _("Name # Modes Min ops Max ops Modes mask # Used\n"));
433 for (i = 0; i < m68hc11_nb_opcode_defs; i++, opc++)
434 {
435 fprintf (file, "%-7.7s %5d %7d %7d 0x%08lx %7d\n",
436 opc->opcode->name,
437 opc->nb_modes,
438 opc->min_operands, opc->max_operands, opc->format, opc->used);
439 }
440}
441
442int
ca43c854 443md_parse_option (int c, char *arg)
60bcf0fa
NC
444{
445 get_default_target ();
446 switch (c)
447 {
986c6f4b 448 /* -S means keep external to 2 bit offset rather than 16 bit one. */
60bcf0fa
NC
449 case OPTION_SHORT_BRANCHS:
450 case 'S':
451 flag_fixed_branchs = 1;
452 break;
453
454 case OPTION_FORCE_LONG_BRANCH:
455 flag_force_long_jumps = 1;
456 break;
457
458 case OPTION_PRINT_INSN_SYNTAX:
459 flag_print_insn_syntax = 1;
460 break;
461
462 case OPTION_PRINT_OPCODES:
463 flag_print_opcodes = 1;
464 break;
465
466 case OPTION_STRICT_DIRECT_MODE:
467 flag_strict_direct_addressing = 0;
468 break;
469
470 case OPTION_GENERATE_EXAMPLE:
471 flag_print_opcodes = 2;
472 break;
473
2f904664
SC
474 case OPTION_MSHORT:
475 elf_flags &= ~E_M68HC11_I32;
476 break;
477
478 case OPTION_MLONG:
479 elf_flags |= E_M68HC11_I32;
480 break;
481
482 case OPTION_MSHORT_DOUBLE:
483 elf_flags &= ~E_M68HC11_F64;
484 break;
485
486 case OPTION_MLONG_DOUBLE:
487 elf_flags |= E_M68HC11_F64;
488 break;
489
60bcf0fa
NC
490 case 'm':
491 if (strcasecmp (arg, "68hc11") == 0)
492 current_architecture = cpu6811;
493 else if (strcasecmp (arg, "68hc12") == 0)
494 current_architecture = cpu6812;
d01030e6
SC
495 else if (strcasecmp (arg, "68hcs12") == 0)
496 current_architecture = cpu6812 | cpu6812s;
60bcf0fa
NC
497 else
498 as_bad (_("Option `%s' is not recognized."), arg);
499 break;
500
501 default:
502 return 0;
503 }
504
505 return 1;
506}
507\f
508symbolS *
ca43c854 509md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
60bcf0fa
NC
510{
511 return 0;
512}
513
fafb6d17 514/* Equal to MAX_PRECISION in atof-ieee.c. */
60bcf0fa
NC
515#define MAX_LITTLENUMS 6
516
517/* Turn a string in input_line_pointer into a floating point constant
bc0d738a
NC
518 of type TYPE, and store the appropriate bytes in *LITP. The number
519 of LITTLENUMS emitted is stored in *SIZEP. An error message is
60bcf0fa 520 returned, or NULL on OK. */
60bcf0fa 521char *
ca43c854 522md_atof (int type, char *litP, int *sizeP)
60bcf0fa
NC
523{
524 int prec;
525 LITTLENUM_TYPE words[MAX_LITTLENUMS];
526 LITTLENUM_TYPE *wordP;
527 char *t;
528
529 switch (type)
530 {
531 case 'f':
532 case 'F':
533 case 's':
534 case 'S':
535 prec = 2;
536 break;
537
538 case 'd':
539 case 'D':
540 case 'r':
541 case 'R':
542 prec = 4;
543 break;
544
545 case 'x':
546 case 'X':
547 prec = 6;
548 break;
549
550 case 'p':
551 case 'P':
552 prec = 6;
553 break;
554
555 default:
556 *sizeP = 0;
557 return _("Bad call to MD_ATOF()");
558 }
559 t = atof_ieee (input_line_pointer, type, words);
560 if (t)
561 input_line_pointer = t;
562
563 *sizeP = prec * sizeof (LITTLENUM_TYPE);
564 for (wordP = words; prec--;)
565 {
566 md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE));
567 litP += sizeof (LITTLENUM_TYPE);
568 }
569 return 0;
570}
571
572valueT
ca43c854 573md_section_align (asection *seg, valueT addr)
60bcf0fa
NC
574{
575 int align = bfd_get_section_alignment (stdoutput, seg);
576 return ((addr + (1 << align) - 1) & (-1 << align));
577}
578
60bcf0fa 579static int
ca43c854 580cmp_opcode (struct m68hc11_opcode *op1, struct m68hc11_opcode *op2)
60bcf0fa
NC
581{
582 return strcmp (op1->name, op2->name);
583}
584
7bfda7eb
SC
585#define IS_CALL_SYMBOL(MODE) \
586(((MODE) & (M6812_OP_PAGE|M6811_OP_IND16)) \
587 == ((M6812_OP_PAGE|M6811_OP_IND16)))
588
60bcf0fa
NC
589/* Initialize the assembler. Create the opcode hash table
590 (sorted on the names) with the M6811 opcode table
591 (from opcode library). */
592void
ca43c854 593md_begin (void)
60bcf0fa
NC
594{
595 char *prev_name = "";
596 struct m68hc11_opcode *opcodes;
597 struct m68hc11_opcode_def *opc = 0;
598 int i, j;
599
600 get_default_target ();
601
602 m68hc11_hash = hash_new ();
603
604 /* Get a writable copy of the opcode table and sort it on the names. */
605 opcodes = (struct m68hc11_opcode *) xmalloc (m68hc11_num_opcodes *
606 sizeof (struct
607 m68hc11_opcode));
608 m68hc11_sorted_opcodes = opcodes;
609 num_opcodes = 0;
610 for (i = 0; i < m68hc11_num_opcodes; i++)
611 {
612 if (m68hc11_opcodes[i].arch & current_architecture)
613 {
614 opcodes[num_opcodes] = m68hc11_opcodes[i];
615 if (opcodes[num_opcodes].name[0] == 'b'
616 && opcodes[num_opcodes].format & M6811_OP_JUMP_REL
617 && !(opcodes[num_opcodes].format & M6811_OP_BITMASK))
618 {
619 num_opcodes++;
620 opcodes[num_opcodes] = m68hc11_opcodes[i];
621 }
622 num_opcodes++;
623 for (j = 0; alias_opcodes[j].name != 0; j++)
624 if (strcmp (m68hc11_opcodes[i].name, alias_opcodes[j].name) == 0)
625 {
626 opcodes[num_opcodes] = m68hc11_opcodes[i];
627 opcodes[num_opcodes].name = alias_opcodes[j].alias;
628 num_opcodes++;
629 break;
630 }
631 }
632 }
1910266d 633 qsort (opcodes, num_opcodes, sizeof (struct m68hc11_opcode),
ca43c854 634 (int (*) (const void*, const void*)) cmp_opcode);
60bcf0fa
NC
635
636 opc = (struct m68hc11_opcode_def *)
637 xmalloc (num_opcodes * sizeof (struct m68hc11_opcode_def));
638 m68hc11_opcode_defs = opc--;
639
640 /* Insert unique names into hash table. The M6811 instruction set
641 has several identical opcode names that have different opcodes based
642 on the operands. This hash table then provides a quick index to
643 the first opcode with a particular name in the opcode table. */
644 for (i = 0; i < num_opcodes; i++, opcodes++)
645 {
646 int expect;
647
648 if (strcmp (prev_name, opcodes->name))
649 {
650 prev_name = (char *) opcodes->name;
651
652 opc++;
653 opc->format = 0;
654 opc->min_operands = 100;
655 opc->max_operands = 0;
656 opc->nb_modes = 0;
657 opc->opcode = opcodes;
658 opc->used = 0;
ca43c854 659 hash_insert (m68hc11_hash, opcodes->name, opc);
60bcf0fa
NC
660 }
661 opc->nb_modes++;
662 opc->format |= opcodes->format;
663
664 /* See how many operands this opcode needs. */
665 expect = 0;
666 if (opcodes->format & M6811_OP_MASK)
667 expect++;
668 if (opcodes->format & M6811_OP_BITMASK)
669 expect++;
670 if (opcodes->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
671 expect++;
672 if (opcodes->format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2))
673 expect++;
7bfda7eb
SC
674 /* Special case for call instruction. */
675 if ((opcodes->format & M6812_OP_PAGE)
676 && !(opcodes->format & M6811_OP_IND16))
677 expect++;
60bcf0fa
NC
678
679 if (expect < opc->min_operands)
680 opc->min_operands = expect;
7bfda7eb
SC
681 if (IS_CALL_SYMBOL (opcodes->format))
682 expect++;
60bcf0fa
NC
683 if (expect > opc->max_operands)
684 opc->max_operands = expect;
685 }
686 opc++;
687 m68hc11_nb_opcode_defs = opc - m68hc11_opcode_defs;
688
689 if (flag_print_opcodes)
690 {
691 print_opcode_list ();
692 exit (EXIT_SUCCESS);
693 }
694}
695
696void
ca43c854 697m68hc11_init_after_args (void)
60bcf0fa
NC
698{
699}
60bcf0fa
NC
700\f
701/* Builtin help. */
702
703/* Return a string that represents the operand format for the instruction.
704 When example is true, this generates an example of operand. This is used
705 to give an example and also to generate a test. */
706static char *
ca43c854 707print_opcode_format (struct m68hc11_opcode *opcode, int example)
60bcf0fa
NC
708{
709 static char buf[128];
710 int format = opcode->format;
711 char *p;
712
713 p = buf;
714 buf[0] = 0;
715 if (format & M6811_OP_IMM8)
716 {
717 if (example)
718 sprintf (p, "#%d", rand () & 0x0FF);
719 else
720 strcpy (p, _("#<imm8>"));
721 p = &p[strlen (p)];
722 }
723
724 if (format & M6811_OP_IMM16)
725 {
726 if (example)
727 sprintf (p, "#%d", rand () & 0x0FFFF);
728 else
729 strcpy (p, _("#<imm16>"));
730 p = &p[strlen (p)];
731 }
732
733 if (format & M6811_OP_IX)
734 {
735 if (example)
736 sprintf (p, "%d,X", rand () & 0x0FF);
737 else
738 strcpy (p, _("<imm8>,X"));
739 p = &p[strlen (p)];
740 }
741
742 if (format & M6811_OP_IY)
743 {
744 if (example)
745 sprintf (p, "%d,X", rand () & 0x0FF);
746 else
747 strcpy (p, _("<imm8>,X"));
748 p = &p[strlen (p)];
749 }
750
751 if (format & M6812_OP_IDX)
752 {
753 if (example)
754 sprintf (p, "%d,X", rand () & 0x0FF);
755 else
756 strcpy (p, "n,r");
757 p = &p[strlen (p)];
758 }
759
7bfda7eb
SC
760 if (format & M6812_OP_PAGE)
761 {
762 if (example)
763 sprintf (p, ", %d", rand () & 0x0FF);
764 else
765 strcpy (p, ", <page>");
766 p = &p[strlen (p)];
767 }
768
60bcf0fa
NC
769 if (format & M6811_OP_DIRECT)
770 {
771 if (example)
772 sprintf (p, "*Z%d", rand () & 0x0FF);
773 else
774 strcpy (p, _("*<abs8>"));
775 p = &p[strlen (p)];
776 }
777
778 if (format & M6811_OP_BITMASK)
779 {
780 if (buf[0])
781 *p++ = ' ';
782
783 if (example)
784 sprintf (p, "#$%02x", rand () & 0x0FF);
785 else
786 strcpy (p, _("#<mask>"));
787
788 p = &p[strlen (p)];
789 if (format & M6811_OP_JUMP_REL)
790 *p++ = ' ';
791 }
792
793 if (format & M6811_OP_IND16)
794 {
795 if (example)
796 sprintf (p, _("symbol%d"), rand () & 0x0FF);
797 else
798 strcpy (p, _("<abs>"));
799
800 p = &p[strlen (p)];
801 }
802
803 if (format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
804 {
805 if (example)
806 {
807 if (format & M6811_OP_BITMASK)
808 {
809 sprintf (p, ".+%d", rand () & 0x7F);
810 }
811 else
812 {
813 sprintf (p, "L%d", rand () & 0x0FF);
814 }
815 }
816 else
817 strcpy (p, _("<label>"));
818 }
819
820 return buf;
821}
822
823/* Prints the list of instructions with the possible operands. */
824static void
ca43c854 825print_opcode_list (void)
60bcf0fa
NC
826{
827 int i;
828 char *prev_name = "";
829 struct m68hc11_opcode *opcodes;
830 int example = flag_print_opcodes == 2;
831
832 if (example)
fafb6d17
NC
833 printf (_("# Example of `%s' instructions\n\t.sect .text\n_start:\n"),
834 default_cpu);
60bcf0fa
NC
835
836 opcodes = m68hc11_sorted_opcodes;
837
838 /* Walk the list sorted on names (by md_begin). We only report
839 one instruction per line, and we collect the different operand
840 formats. */
841 for (i = 0; i < num_opcodes; i++, opcodes++)
842 {
843 char *fmt = print_opcode_format (opcodes, example);
844
845 if (example)
846 {
847 printf ("L%d:\t", i);
848 printf ("%s %s\n", opcodes->name, fmt);
849 }
850 else
851 {
852 if (strcmp (prev_name, opcodes->name))
853 {
854 if (i > 0)
855 printf ("\n");
856
857 printf ("%-5.5s ", opcodes->name);
858 prev_name = (char *) opcodes->name;
859 }
860 if (fmt[0])
861 printf (" [%s]", fmt);
862 }
863 }
864 printf ("\n");
865}
866
60bcf0fa
NC
867/* Print the instruction format. This operation is called when some
868 instruction is not correct. Instruction format is printed as an
869 error message. */
870static void
ca43c854 871print_insn_format (char *name)
60bcf0fa
NC
872{
873 struct m68hc11_opcode_def *opc;
874 struct m68hc11_opcode *opcode;
875 char buf[128];
876
877 opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash, name);
878 if (opc == NULL)
879 {
880 as_bad (_("Instruction `%s' is not recognized."), name);
881 return;
882 }
883 opcode = opc->opcode;
884
885 as_bad (_("Instruction formats for `%s':"), name);
886 do
887 {
888 char *fmt;
889
27302d63 890 fmt = print_opcode_format (opcode, 0);
60bcf0fa
NC
891 sprintf (buf, "\t%-5.5s %s", opcode->name, fmt);
892
893 as_bad ("%s", buf);
894 opcode++;
895 }
896 while (strcmp (opcode->name, name) == 0);
897}
60bcf0fa
NC
898\f
899/* Analysis of 68HC11 and 68HC12 operands. */
900
901/* reg_name_search() finds the register number given its name.
902 Returns the register number or REG_NONE on failure. */
903static register_id
ca43c854 904reg_name_search (char *name)
60bcf0fa
NC
905{
906 if (strcasecmp (name, "x") == 0 || strcasecmp (name, "ix") == 0)
907 return REG_X;
908 if (strcasecmp (name, "y") == 0 || strcasecmp (name, "iy") == 0)
909 return REG_Y;
910 if (strcasecmp (name, "a") == 0)
911 return REG_A;
912 if (strcasecmp (name, "b") == 0)
913 return REG_B;
914 if (strcasecmp (name, "d") == 0)
915 return REG_D;
916 if (strcasecmp (name, "sp") == 0)
917 return REG_SP;
918 if (strcasecmp (name, "pc") == 0)
919 return REG_PC;
920 if (strcasecmp (name, "ccr") == 0)
921 return REG_CCR;
922
923 return REG_NONE;
924}
925
926static char *
ca43c854 927skip_whites (char *p)
60bcf0fa
NC
928{
929 while (*p == ' ' || *p == '\t')
930 p++;
931
932 return p;
933}
934
fafb6d17 935/* Check the string at input_line_pointer
60bcf0fa
NC
936 to see if it is a valid register name. */
937static register_id
ca43c854 938register_name (void)
60bcf0fa
NC
939{
940 register_id reg_number;
941 char c, *p = input_line_pointer;
942
943 if (!is_name_beginner (*p++))
944 return REG_NONE;
945
946 while (is_part_of_name (*p++))
947 continue;
948
949 c = *--p;
950 if (c)
951 *p++ = 0;
952
fafb6d17 953 /* Look to see if it's in the register table. */
60bcf0fa
NC
954 reg_number = reg_name_search (input_line_pointer);
955 if (reg_number != REG_NONE)
956 {
957 if (c)
958 *--p = c;
959
960 input_line_pointer = p;
961 return reg_number;
962 }
963 if (c)
964 *--p = c;
965
966 return reg_number;
967}
577300ce
SC
968#define M6811_OP_CALL_ADDR 0x00800000
969#define M6811_OP_PAGE_ADDR 0x04000000
60bcf0fa 970
fafb6d17 971/* Parse a string of operands and return an array of expressions.
60bcf0fa 972
7bfda7eb
SC
973 Operand mode[0] mode[1] exp[0] exp[1]
974 #n M6811_OP_IMM16 - O_*
975 *<exp> M6811_OP_DIRECT - O_*
976 .{+-}<exp> M6811_OP_JUMP_REL - O_*
977 <exp> M6811_OP_IND16 - O_*
978 ,r N,r M6812_OP_IDX M6812_OP_REG O_constant O_register
979 n,-r M6812_PRE_DEC M6812_OP_REG O_constant O_register
980 n,+r M6812_PRE_INC " "
981 n,r- M6812_POST_DEC " "
982 n,r+ M6812_POST_INC " "
983 A,r B,r D,r M6811_OP_REG M6812_OP_REG O_register O_register
984 [D,r] M6811_OP_D_IDX M6812_OP_REG O_register O_register
985 [n,r] M6811_OP_D_IDX_2 M6812_OP_REG O_constant O_register */
60bcf0fa 986static int
ca43c854 987get_operand (operand *oper, int which, long opmode)
60bcf0fa
NC
988{
989 char *p = input_line_pointer;
990 int mode;
991 register_id reg;
992
993 oper->exp.X_op = O_absent;
994 oper->reg1 = REG_NONE;
995 oper->reg2 = REG_NONE;
996 mode = M6811_OP_NONE;
997
998 p = skip_whites (p);
999
1000 if (*p == 0 || *p == '\n' || *p == '\r')
1001 {
1002 input_line_pointer = p;
1003 return 0;
1004 }
1005
1006 if (*p == '*' && (opmode & (M6811_OP_DIRECT | M6811_OP_IND16)))
1007 {
1008 mode = M6811_OP_DIRECT;
1009 p++;
1010 }
1011 else if (*p == '#')
1012 {
1013 if (!(opmode & (M6811_OP_IMM8 | M6811_OP_IMM16 | M6811_OP_BITMASK)))
1014 {
1015 as_bad (_("Immediate operand is not allowed for operand %d."),
fafb6d17 1016 which);
60bcf0fa
NC
1017 return -1;
1018 }
1019
1020 mode = M6811_OP_IMM16;
1021 p++;
1022 if (strncmp (p, "%hi", 3) == 0)
1023 {
1024 p += 3;
1025 mode |= M6811_OP_HIGH_ADDR;
1026 }
1027 else if (strncmp (p, "%lo", 3) == 0)
1028 {
1029 p += 3;
1030 mode |= M6811_OP_LOW_ADDR;
1031 }
577300ce
SC
1032 /* %page modifier is used to obtain only the page number
1033 of the address of a function. */
1034 else if (strncmp (p, "%page", 5) == 0)
1035 {
1036 p += 5;
1037 mode |= M6811_OP_PAGE_ADDR;
1038 }
1039
1040 /* %addr modifier is used to obtain the physical address part
1041 of the function (16-bit). For 68HC12 the function will be
1042 mapped in the 16K window at 0x8000 and the value will be
1043 within that window (although the function address may not fit
1044 in 16-bit). See bfd/elf32-m68hc12.c for the translation. */
1045 else if (strncmp (p, "%addr", 5) == 0)
1046 {
1047 p += 5;
1048 mode |= M6811_OP_CALL_ADDR;
1049 }
60bcf0fa
NC
1050 }
1051 else if (*p == '.' && (p[1] == '+' || p[1] == '-'))
1052 {
1053 p++;
1054 mode = M6811_OP_JUMP_REL;
1055 }
1056 else if (*p == '[')
1057 {
1058 if (current_architecture & cpu6811)
1059 as_bad (_("Indirect indexed addressing is not valid for 68HC11."));
1060
1061 p++;
7bfda7eb 1062 mode = M6812_OP_D_IDX;
60bcf0fa
NC
1063 p = skip_whites (p);
1064 }
1065 else if (*p == ',') /* Special handling of ,x and ,y. */
1066 {
1067 p++;
1068 input_line_pointer = p;
1069
1070 reg = register_name ();
1071 if (reg != REG_NONE)
1072 {
1073 oper->reg1 = reg;
1074 oper->exp.X_op = O_constant;
1075 oper->exp.X_add_number = 0;
1076 oper->mode = M6812_OP_IDX;
1077 return 1;
1078 }
1079 as_bad (_("Spurious `,' or bad indirect register addressing mode."));
1080 return -1;
1081 }
577300ce
SC
1082 /* Handle 68HC12 page specification in 'call foo,%page(bar)'. */
1083 else if ((opmode & M6812_OP_PAGE) && strncmp (p, "%page", 5) == 0)
1084 {
1085 p += 5;
1086 mode = M6811_OP_PAGE_ADDR | M6812_OP_PAGE | M6811_OP_IND16;
1087 }
60bcf0fa
NC
1088 input_line_pointer = p;
1089
7bfda7eb 1090 if (mode == M6811_OP_NONE || mode == M6812_OP_D_IDX)
60bcf0fa
NC
1091 reg = register_name ();
1092 else
1093 reg = REG_NONE;
1094
1095 if (reg != REG_NONE)
1096 {
1097 p = skip_whites (input_line_pointer);
7bfda7eb 1098 if (*p == ']' && mode == M6812_OP_D_IDX)
60bcf0fa
NC
1099 {
1100 as_bad
1101 (_("Missing second register or offset for indexed-indirect mode."));
1102 return -1;
1103 }
1104
1105 oper->reg1 = reg;
1106 oper->mode = mode | M6812_OP_REG;
1107 if (*p != ',')
1108 {
7bfda7eb 1109 if (mode == M6812_OP_D_IDX)
60bcf0fa
NC
1110 {
1111 as_bad (_("Missing second register for indexed-indirect mode."));
1112 return -1;
1113 }
1114 return 1;
1115 }
1116
1117 p++;
1118 input_line_pointer = p;
1119 reg = register_name ();
1120 if (reg != REG_NONE)
1121 {
1122 p = skip_whites (input_line_pointer);
7bfda7eb 1123 if (mode == M6812_OP_D_IDX)
60bcf0fa
NC
1124 {
1125 if (*p != ']')
1126 {
1127 as_bad (_("Missing `]' to close indexed-indirect mode."));
1128 return -1;
1129 }
1130 p++;
7bfda7eb 1131 oper->mode = M6812_OP_D_IDX;
60bcf0fa
NC
1132 }
1133 input_line_pointer = p;
1134
1135 oper->reg2 = reg;
1136 return 1;
1137 }
1138 return 1;
1139 }
1140
1141 /* In MRI mode, isolate the operand because we can't distinguish
1142 operands from comments. */
1143 if (flag_mri)
1144 {
1145 char c = 0;
1146
1147 p = skip_whites (p);
1148 while (*p && *p != ' ' && *p != '\t')
1149 p++;
1150
1151 if (*p)
1152 {
1153 c = *p;
1154 *p = 0;
1155 }
1156
1157 /* Parse as an expression. */
1158 expression (&oper->exp);
1159
1160 if (c)
1161 {
1162 *p = c;
1163 }
1164 }
1165 else
1166 {
1167 expression (&oper->exp);
1168 }
1169
1170 if (oper->exp.X_op == O_illegal)
1171 {
1172 as_bad (_("Illegal operand."));
1173 return -1;
1174 }
1175 else if (oper->exp.X_op == O_absent)
1176 {
1177 as_bad (_("Missing operand."));
1178 return -1;
1179 }
1180
1181 p = input_line_pointer;
1182
1183 if (mode == M6811_OP_NONE || mode == M6811_OP_DIRECT
7bfda7eb 1184 || mode == M6812_OP_D_IDX)
60bcf0fa
NC
1185 {
1186 p = skip_whites (input_line_pointer);
1187
1188 if (*p == ',')
1189 {
098f2ec3
KH
1190 int possible_mode = M6811_OP_NONE;
1191 char *old_input_line;
7bfda7eb
SC
1192
1193 old_input_line = p;
60bcf0fa
NC
1194 p++;
1195
1196 /* 68HC12 pre increment or decrement. */
1197 if (mode == M6811_OP_NONE)
1198 {
1199 if (*p == '-')
1200 {
ae3e85dd 1201 possible_mode = M6812_PRE_DEC;
60bcf0fa 1202 p++;
60bcf0fa
NC
1203 }
1204 else if (*p == '+')
1205 {
ae3e85dd 1206 possible_mode = M6812_PRE_INC;
60bcf0fa 1207 p++;
60bcf0fa
NC
1208 }
1209 p = skip_whites (p);
1210 }
1211 input_line_pointer = p;
1212 reg = register_name ();
1213
098f2ec3
KH
1214 /* Backtrack if we have a valid constant expression and
1215 it does not correspond to the offset of the 68HC12 indexed
1216 addressing mode (as in N,x). */
1217 if (reg == REG_NONE && mode == M6811_OP_NONE
1218 && possible_mode != M6811_OP_NONE)
1219 {
1220 oper->mode = M6811_OP_IND16 | M6811_OP_JUMP_REL;
1221 input_line_pointer = skip_whites (old_input_line);
1222 return 1;
1223 }
1224
1225 if (possible_mode != M6811_OP_NONE)
1226 mode = possible_mode;
1227
1228 if ((current_architecture & cpu6811)
1229 && possible_mode != M6811_OP_NONE)
1230 as_bad (_("Pre-increment mode is not valid for 68HC11"));
fafb6d17 1231 /* Backtrack. */
60bcf0fa
NC
1232 if (which == 0 && opmode & M6812_OP_IDX_P2
1233 && reg != REG_X && reg != REG_Y
1234 && reg != REG_PC && reg != REG_SP)
1235 {
1236 reg = REG_NONE;
1237 input_line_pointer = p;
1238 }
1239
1240 if (reg == REG_NONE && mode != M6811_OP_DIRECT
1241 && !(mode == M6811_OP_NONE && opmode & M6811_OP_IND16))
1242 {
1243 as_bad (_("Wrong register in register indirect mode."));
1244 return -1;
1245 }
7bfda7eb 1246 if (mode == M6812_OP_D_IDX)
60bcf0fa
NC
1247 {
1248 p = skip_whites (input_line_pointer);
1249 if (*p++ != ']')
1250 {
1251 as_bad (_("Missing `]' to close register indirect operand."));
1252 return -1;
1253 }
1254 input_line_pointer = p;
7bfda7eb
SC
1255 oper->reg1 = reg;
1256 oper->mode = M6812_OP_D_IDX_2;
1257 return 1;
60bcf0fa
NC
1258 }
1259 if (reg != REG_NONE)
1260 {
1261 oper->reg1 = reg;
1262 if (mode == M6811_OP_NONE)
1263 {
1264 p = input_line_pointer;
1265 if (*p == '-')
1266 {
1267 mode = M6812_POST_DEC;
1268 p++;
1269 if (current_architecture & cpu6811)
1270 as_bad
1271 (_("Post-decrement mode is not valid for 68HC11."));
1272 }
1273 else if (*p == '+')
1274 {
1275 mode = M6812_POST_INC;
1276 p++;
1277 if (current_architecture & cpu6811)
1278 as_bad
1279 (_("Post-increment mode is not valid for 68HC11."));
1280 }
1281 else
1282 mode = M6812_OP_IDX;
1283
1284 input_line_pointer = p;
1285 }
1286 else
1287 mode |= M6812_OP_IDX;
1288
1289 oper->mode = mode;
1290 return 1;
1291 }
7bfda7eb 1292 input_line_pointer = old_input_line;
60bcf0fa
NC
1293 }
1294
1295 if (mode == M6812_OP_D_IDX_2)
1296 {
1297 as_bad (_("Invalid indexed indirect mode."));
1298 return -1;
1299 }
1300 }
1301
1302 /* If the mode is not known until now, this is either a label
1303 or an indirect address. */
1304 if (mode == M6811_OP_NONE)
fafb6d17 1305 mode = M6811_OP_IND16 | M6811_OP_JUMP_REL;
60bcf0fa
NC
1306
1307 p = input_line_pointer;
1308 while (*p == ' ' || *p == '\t')
1309 p++;
1310 input_line_pointer = p;
1311 oper->mode = mode;
1312
1313 return 1;
1314}
1315
1316#define M6812_AUTO_INC_DEC (M6812_PRE_INC | M6812_PRE_DEC \
1317 | M6812_POST_INC | M6812_POST_DEC)
1318
1319/* Checks that the number 'num' fits for a given mode. */
1320static int
ca43c854 1321check_range (long num, int mode)
60bcf0fa
NC
1322{
1323 /* Auto increment and decrement are ok for [-8..8] without 0. */
1324 if (mode & M6812_AUTO_INC_DEC)
fafb6d17 1325 return (num != 0 && num <= 8 && num >= -8);
60bcf0fa 1326
986c6f4b 1327 /* The 68HC12 supports 5, 9 and 16-bit offsets. */
60bcf0fa 1328 if (mode & (M6812_INDEXED_IND | M6812_INDEXED | M6812_OP_IDX))
fafb6d17 1329 mode = M6811_OP_IND16;
60bcf0fa
NC
1330
1331 if (mode & M6812_OP_JUMP_REL16)
1332 mode = M6811_OP_IND16;
1333
7bfda7eb 1334 mode &= ~M6811_OP_BRANCH;
60bcf0fa
NC
1335 switch (mode)
1336 {
1337 case M6811_OP_IX:
1338 case M6811_OP_IY:
1339 case M6811_OP_DIRECT:
1340 return (num >= 0 && num <= 255) ? 1 : 0;
1341
1342 case M6811_OP_BITMASK:
1343 case M6811_OP_IMM8:
7bfda7eb 1344 case M6812_OP_PAGE:
60bcf0fa
NC
1345 return (((num & 0xFFFFFF00) == 0) || ((num & 0xFFFFFF00) == 0xFFFFFF00))
1346 ? 1 : 0;
1347
1348 case M6811_OP_JUMP_REL:
1349 return (num >= -128 && num <= 127) ? 1 : 0;
1350
1351 case M6811_OP_IND16:
7bfda7eb 1352 case M6811_OP_IND16 | M6812_OP_PAGE:
60bcf0fa
NC
1353 case M6811_OP_IMM16:
1354 return (((num & 0xFFFF0000) == 0) || ((num & 0xFFFF0000) == 0xFFFF0000))
1355 ? 1 : 0;
1356
1357 case M6812_OP_IBCC_MARKER:
1358 case M6812_OP_TBCC_MARKER:
1359 case M6812_OP_DBCC_MARKER:
1360 return (num >= -256 && num <= 255) ? 1 : 0;
1361
1362 case M6812_OP_TRAP_ID:
1363 return ((num >= 0x30 && num <= 0x39)
1364 || (num >= 0x40 && num <= 0x0ff)) ? 1 : 0;
1365
1366 default:
1367 return 0;
1368 }
1369}
60bcf0fa
NC
1370\f
1371/* Gas fixup generation. */
1372
1373/* Put a 1 byte expression described by 'oper'. If this expression contains
1374 unresolved symbols, generate an 8-bit fixup. */
1375static void
ca43c854 1376fixup8 (expressionS *oper, int mode, int opmode)
60bcf0fa
NC
1377{
1378 char *f;
1379
1380 f = frag_more (1);
1381
1382 if (oper->X_op == O_constant)
1383 {
1384 if (mode & M6812_OP_TRAP_ID
1385 && !check_range (oper->X_add_number, M6812_OP_TRAP_ID))
1386 {
1387 static char trap_id_warn_once = 0;
1388
1389 as_bad (_("Trap id `%ld' is out of range."), oper->X_add_number);
1390 if (trap_id_warn_once == 0)
1391 {
1392 trap_id_warn_once = 1;
1393 as_bad (_("Trap id must be within [0x30..0x39] or [0x40..0xff]."));
1394 }
1395 }
1396
1397 if (!(mode & M6812_OP_TRAP_ID)
1398 && !check_range (oper->X_add_number, mode))
1399 {
1400 as_bad (_("Operand out of 8-bit range: `%ld'."), oper->X_add_number);
1401 }
1402 number_to_chars_bigendian (f, oper->X_add_number & 0x0FF, 1);
1403 }
1404 else if (oper->X_op != O_register)
1405 {
1406 if (mode & M6812_OP_TRAP_ID)
1407 as_bad (_("The trap id must be a constant."));
1408
1409 if (mode == M6811_OP_JUMP_REL)
1410 {
1411 fixS *fixp;
1412
1413 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
b34976b6 1414 oper, TRUE, BFD_RELOC_8_PCREL);
60bcf0fa
NC
1415 fixp->fx_pcrel_adjust = 1;
1416 }
1417 else
1418 {
577300ce
SC
1419 fixS *fixp;
1420 int reloc;
1421
1422 /* Now create an 8-bit fixup. If there was some %hi, %lo
1423 or %page modifier, generate the reloc accordingly. */
1424 if (opmode & M6811_OP_HIGH_ADDR)
1425 reloc = BFD_RELOC_M68HC11_HI8;
1426 else if (opmode & M6811_OP_LOW_ADDR)
1427 reloc = BFD_RELOC_M68HC11_LO8;
1428 else if (opmode & M6811_OP_PAGE_ADDR)
1429 reloc = BFD_RELOC_M68HC11_PAGE;
1430 else
1431 reloc = BFD_RELOC_8;
1432
1433 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
1434 oper, FALSE, reloc);
1435 if (reloc != BFD_RELOC_8)
1436 fixp->fx_no_overflow = 1;
60bcf0fa
NC
1437 }
1438 number_to_chars_bigendian (f, 0, 1);
1439 }
1440 else
1441 {
1442 as_fatal (_("Operand `%x' not recognized in fixup8."), oper->X_op);
1443 }
1444}
1445
986c6f4b 1446/* Put a 2 byte expression described by 'oper'. If this expression contains
60bcf0fa
NC
1447 unresolved symbols, generate a 16-bit fixup. */
1448static void
ca43c854 1449fixup16 (expressionS *oper, int mode, int opmode ATTRIBUTE_UNUSED)
60bcf0fa
NC
1450{
1451 char *f;
1452
1453 f = frag_more (2);
1454
1455 if (oper->X_op == O_constant)
1456 {
1457 if (!check_range (oper->X_add_number, mode))
1458 {
1459 as_bad (_("Operand out of 16-bit range: `%ld'."),
fafb6d17 1460 oper->X_add_number);
60bcf0fa
NC
1461 }
1462 number_to_chars_bigendian (f, oper->X_add_number & 0x0FFFF, 2);
1463 }
1464 else if (oper->X_op != O_register)
1465 {
1466 fixS *fixp;
577300ce
SC
1467 int reloc;
1468
1469 if ((opmode & M6811_OP_CALL_ADDR) && (mode & M6811_OP_IMM16))
1470 reloc = BFD_RELOC_M68HC11_LO16;
1471 else if (mode & M6812_OP_JUMP_REL16)
1472 reloc = BFD_RELOC_16_PCREL;
1473 else if (mode & M6812_OP_PAGE)
1474 reloc = BFD_RELOC_M68HC11_LO16;
1475 else
1476 reloc = BFD_RELOC_16;
60bcf0fa
NC
1477
1478 /* Now create a 16-bit fixup. */
1479 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 2,
1480 oper,
577300ce
SC
1481 reloc == BFD_RELOC_16_PCREL,
1482 reloc);
60bcf0fa 1483 number_to_chars_bigendian (f, 0, 2);
577300ce 1484 if (reloc == BFD_RELOC_16_PCREL)
60bcf0fa 1485 fixp->fx_pcrel_adjust = 2;
577300ce
SC
1486 if (reloc == BFD_RELOC_M68HC11_LO16)
1487 fixp->fx_no_overflow = 1;
60bcf0fa
NC
1488 }
1489 else
1490 {
1491 as_fatal (_("Operand `%x' not recognized in fixup16."), oper->X_op);
1492 }
1493}
7bfda7eb
SC
1494
1495/* Put a 3 byte expression described by 'oper'. If this expression contains
1496 unresolved symbols, generate a 24-bit fixup. */
1497static void
ca43c854 1498fixup24 (expressionS *oper, int mode, int opmode ATTRIBUTE_UNUSED)
7bfda7eb
SC
1499{
1500 char *f;
1501
1502 f = frag_more (3);
1503
1504 if (oper->X_op == O_constant)
1505 {
1506 if (!check_range (oper->X_add_number, mode))
1507 {
1508 as_bad (_("Operand out of 16-bit range: `%ld'."),
1509 oper->X_add_number);
1510 }
1511 number_to_chars_bigendian (f, oper->X_add_number & 0x0FFFFFF, 3);
1512 }
1513 else if (oper->X_op != O_register)
1514 {
1515 fixS *fixp;
1516
1517 /* Now create a 24-bit fixup. */
1518 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 2,
b34976b6 1519 oper, FALSE, BFD_RELOC_M68HC11_24);
7bfda7eb
SC
1520 number_to_chars_bigendian (f, 0, 3);
1521 }
1522 else
1523 {
1524 as_fatal (_("Operand `%x' not recognized in fixup16."), oper->X_op);
1525 }
1526}
60bcf0fa
NC
1527\f
1528/* 68HC11 and 68HC12 code generation. */
1529
1530/* Translate the short branch/bsr instruction into a long branch. */
1531static unsigned char
ca43c854 1532convert_branch (unsigned char code)
60bcf0fa
NC
1533{
1534 if (IS_OPCODE (code, M6812_BSR))
1535 return M6812_JSR;
1536 else if (IS_OPCODE (code, M6811_BSR))
1537 return M6811_JSR;
1538 else if (IS_OPCODE (code, M6811_BRA))
1539 return (current_architecture & cpu6812) ? M6812_JMP : M6811_JMP;
1540 else
1541 as_fatal (_("Unexpected branch conversion with `%x'"), code);
1542
1543 /* Keep gcc happy. */
1544 return M6811_JSR;
1545}
1546
1547/* Start a new insn that contains at least 'size' bytes. Record the
1548 line information of that insn in the dwarf2 debug sections. */
fafb6d17 1549static char *
ca43c854 1550m68hc11_new_insn (int size)
60bcf0fa 1551{
fafb6d17 1552 char *f;
60bcf0fa
NC
1553
1554 f = frag_more (size);
1555
4dc7ead9 1556 dwarf2_emit_insn (size);
fafb6d17 1557
60bcf0fa
NC
1558 return f;
1559}
1560
1561/* Builds a jump instruction (bra, bcc, bsr). */
1562static void
ca43c854
SC
1563build_jump_insn (struct m68hc11_opcode *opcode, operand operands[],
1564 int nb_operands, int jmp_mode)
60bcf0fa
NC
1565{
1566 unsigned char code;
60bcf0fa
NC
1567 char *f;
1568 unsigned long n;
e371935f
SC
1569 fragS *frag;
1570 int where;
60bcf0fa 1571
67c1ffbe 1572 /* The relative branch conversion is not supported for
60bcf0fa
NC
1573 brclr and brset. */
1574 assert ((opcode->format & M6811_OP_BITMASK) == 0);
1575 assert (nb_operands == 1);
1576 assert (operands[0].reg1 == REG_NONE && operands[0].reg2 == REG_NONE);
1577
1578 code = opcode->opcode;
60bcf0fa
NC
1579
1580 n = operands[0].exp.X_add_number;
1581
1582 /* Turn into a long branch:
1583 - when force long branch option (and not for jbcc pseudos),
1584 - when jbcc and the constant is out of -128..127 range,
1585 - when branch optimization is allowed and branch out of range. */
1586 if ((jmp_mode == 0 && flag_force_long_jumps)
1587 || (operands[0].exp.X_op == O_constant
1588 && (!check_range (n, opcode->format) &&
1589 (jmp_mode == 1 || flag_fixed_branchs == 0))))
1590 {
e371935f
SC
1591 frag = frag_now;
1592 where = frag_now_fix ();
1593
1594 fix_new (frag_now, frag_now_fix (), 1,
1595 &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
1596
60bcf0fa
NC
1597 if (code == M6811_BSR || code == M6811_BRA || code == M6812_BSR)
1598 {
1599 code = convert_branch (code);
1600
1601 f = m68hc11_new_insn (1);
1602 number_to_chars_bigendian (f, code, 1);
1603 }
1604 else if (current_architecture & cpu6812)
1605 {
1606 /* 68HC12: translate the bcc into a lbcc. */
1607 f = m68hc11_new_insn (2);
1608 number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1);
1609 number_to_chars_bigendian (f + 1, code, 1);
1610 fixup16 (&operands[0].exp, M6812_OP_JUMP_REL16,
1611 M6812_OP_JUMP_REL16);
1612 return;
1613 }
1614 else
1615 {
1616 /* 68HC11: translate the bcc into b!cc +3; jmp <L>. */
1617 f = m68hc11_new_insn (3);
1618 code ^= 1;
1619 number_to_chars_bigendian (f, code, 1);
1620 number_to_chars_bigendian (f + 1, 3, 1);
1621 number_to_chars_bigendian (f + 2, M6811_JMP, 1);
1622 }
1623 fixup16 (&operands[0].exp, M6811_OP_IND16, M6811_OP_IND16);
1624 return;
1625 }
1626
1627 /* Branch with a constant that must fit in 8-bits. */
1628 if (operands[0].exp.X_op == O_constant)
1629 {
1630 if (!check_range (n, opcode->format))
1631 {
1632 as_bad (_("Operand out of range for a relative branch: `%ld'"),
1633 n);
1634 }
1635 else if (opcode->format & M6812_OP_JUMP_REL16)
1636 {
1637 f = m68hc11_new_insn (4);
1638 number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1);
1639 number_to_chars_bigendian (f + 1, code, 1);
1640 number_to_chars_bigendian (f + 2, n & 0x0ffff, 2);
1641 }
1642 else
1643 {
1644 f = m68hc11_new_insn (2);
1645 number_to_chars_bigendian (f, code, 1);
1646 number_to_chars_bigendian (f + 1, n & 0x0FF, 1);
1647 }
1648 }
1649 else if (opcode->format & M6812_OP_JUMP_REL16)
1650 {
e371935f
SC
1651 frag = frag_now;
1652 where = frag_now_fix ();
1653
1654 fix_new (frag_now, frag_now_fix (), 1,
1655 &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
1656
60bcf0fa
NC
1657 f = m68hc11_new_insn (2);
1658 number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1);
1659 number_to_chars_bigendian (f + 1, code, 1);
1660 fixup16 (&operands[0].exp, M6812_OP_JUMP_REL16, M6812_OP_JUMP_REL16);
1661 }
1662 else
1663 {
1664 char *opcode;
1665
e371935f
SC
1666 frag = frag_now;
1667 where = frag_now_fix ();
1668
1669 fix_new (frag_now, frag_now_fix (), 1,
1670 &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
1671
60bcf0fa
NC
1672 /* Branch offset must fit in 8-bits, don't do some relax. */
1673 if (jmp_mode == 0 && flag_fixed_branchs)
1674 {
1675 opcode = m68hc11_new_insn (1);
1676 number_to_chars_bigendian (opcode, code, 1);
1677 fixup8 (&operands[0].exp, M6811_OP_JUMP_REL, M6811_OP_JUMP_REL);
1678 }
1679
1680 /* bra/bsr made be changed into jmp/jsr. */
1681 else if (code == M6811_BSR || code == M6811_BRA || code == M6812_BSR)
1682 {
4fe7ef96
SC
1683 /* Allocate worst case storage. */
1684 opcode = m68hc11_new_insn (3);
60bcf0fa
NC
1685 number_to_chars_bigendian (opcode, code, 1);
1686 number_to_chars_bigendian (opcode + 1, 0, 1);
4fe7ef96
SC
1687 frag_variant (rs_machine_dependent, 1, 1,
1688 ENCODE_RELAX (STATE_PC_RELATIVE, STATE_UNDF),
1689 operands[0].exp.X_add_symbol, (offsetT) n,
1690 opcode);
60bcf0fa
NC
1691 }
1692 else if (current_architecture & cpu6812)
1693 {
1694 opcode = m68hc11_new_insn (2);
1695 number_to_chars_bigendian (opcode, code, 1);
1696 number_to_chars_bigendian (opcode + 1, 0, 1);
1697 frag_var (rs_machine_dependent, 2, 2,
1698 ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_UNDF),
1699 operands[0].exp.X_add_symbol, (offsetT) n, opcode);
1700 }
1701 else
1702 {
1703 opcode = m68hc11_new_insn (2);
1704 number_to_chars_bigendian (opcode, code, 1);
1705 number_to_chars_bigendian (opcode + 1, 0, 1);
1706 frag_var (rs_machine_dependent, 3, 3,
1707 ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_UNDF),
1708 operands[0].exp.X_add_symbol, (offsetT) n, opcode);
1709 }
1710 }
1711}
1712
1713/* Builds a dbne/dbeq/tbne/tbeq instruction. */
1714static void
ca43c854
SC
1715build_dbranch_insn (struct m68hc11_opcode *opcode, operand operands[],
1716 int nb_operands, int jmp_mode)
60bcf0fa
NC
1717{
1718 unsigned char code;
60bcf0fa
NC
1719 char *f;
1720 unsigned long n;
1721
67c1ffbe 1722 /* The relative branch conversion is not supported for
60bcf0fa
NC
1723 brclr and brset. */
1724 assert ((opcode->format & M6811_OP_BITMASK) == 0);
1725 assert (nb_operands == 2);
1726 assert (operands[0].reg1 != REG_NONE);
1727
1728 code = opcode->opcode & 0x0FF;
60bcf0fa
NC
1729
1730 f = m68hc11_new_insn (1);
1731 number_to_chars_bigendian (f, code, 1);
1732
1733 n = operands[1].exp.X_add_number;
1734 code = operands[0].reg1;
1735
1736 if (operands[0].reg1 == REG_NONE || operands[0].reg1 == REG_CCR
1737 || operands[0].reg1 == REG_PC)
1738 as_bad (_("Invalid register for dbcc/tbcc instruction."));
1739
1740 if (opcode->format & M6812_OP_IBCC_MARKER)
1741 code |= 0x80;
1742 else if (opcode->format & M6812_OP_TBCC_MARKER)
1743 code |= 0x40;
1744
1745 if (!(opcode->format & M6812_OP_EQ_MARKER))
1746 code |= 0x20;
1747
1748 /* Turn into a long branch:
1749 - when force long branch option (and not for jbcc pseudos),
1750 - when jdbcc and the constant is out of -256..255 range,
1751 - when branch optimization is allowed and branch out of range. */
1752 if ((jmp_mode == 0 && flag_force_long_jumps)
1753 || (operands[1].exp.X_op == O_constant
1754 && (!check_range (n, M6812_OP_IBCC_MARKER) &&
1755 (jmp_mode == 1 || flag_fixed_branchs == 0))))
1756 {
1757 f = frag_more (2);
1758 code ^= 0x20;
1759 number_to_chars_bigendian (f, code, 1);
1760 number_to_chars_bigendian (f + 1, M6812_JMP, 1);
1761 fixup16 (&operands[0].exp, M6811_OP_IND16, M6811_OP_IND16);
1762 return;
1763 }
1764
1765 /* Branch with a constant that must fit in 9-bits. */
1766 if (operands[1].exp.X_op == O_constant)
1767 {
1768 if (!check_range (n, M6812_OP_IBCC_MARKER))
1769 {
1770 as_bad (_("Operand out of range for a relative branch: `%ld'"),
1771 n);
1772 }
1773 else
1774 {
1775 if ((long) n < 0)
1776 code |= 0x10;
1777
1778 f = frag_more (2);
1779 number_to_chars_bigendian (f, code, 1);
1780 number_to_chars_bigendian (f + 1, n & 0x0FF, 1);
1781 }
1782 }
1783 else
1784 {
1785 /* Branch offset must fit in 8-bits, don't do some relax. */
1786 if (jmp_mode == 0 && flag_fixed_branchs)
1787 {
1788 fixup8 (&operands[0].exp, M6811_OP_JUMP_REL, M6811_OP_JUMP_REL);
1789 }
1790
1791 else
1792 {
1793 f = frag_more (2);
1794 number_to_chars_bigendian (f, code, 1);
1795 number_to_chars_bigendian (f + 1, 0, 1);
1796 frag_var (rs_machine_dependent, 3, 3,
1797 ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_UNDF),
1798 operands[1].exp.X_add_symbol, (offsetT) n, f);
1799 }
1800 }
1801}
1802
1803#define OP_EXTENDED (M6811_OP_PAGE2 | M6811_OP_PAGE3 | M6811_OP_PAGE4)
1804
1805/* Assemble the post index byte for 68HC12 extended addressing modes. */
1806static int
ca43c854 1807build_indexed_byte (operand *op, int format ATTRIBUTE_UNUSED, int move_insn)
60bcf0fa
NC
1808{
1809 unsigned char byte = 0;
1810 char *f;
1811 int mode;
1812 long val;
1813
1814 val = op->exp.X_add_number;
1815 mode = op->mode;
1816 if (mode & M6812_AUTO_INC_DEC)
1817 {
1818 byte = 0x20;
1819 if (mode & (M6812_POST_INC | M6812_POST_DEC))
1820 byte |= 0x10;
1821
1822 if (op->exp.X_op == O_constant)
1823 {
1824 if (!check_range (val, mode))
1825 {
1826 as_bad (_("Increment/decrement value is out of range: `%ld'."),
fafb6d17 1827 val);
60bcf0fa
NC
1828 }
1829 if (mode & (M6812_POST_INC | M6812_PRE_INC))
1830 byte |= (val - 1) & 0x07;
1831 else
1832 byte |= (8 - ((val) & 7)) | 0x8;
1833 }
1834 switch (op->reg1)
1835 {
1836 case REG_NONE:
1837 as_fatal (_("Expecting a register."));
1838
1839 case REG_X:
1840 byte |= 0;
1841 break;
1842
1843 case REG_Y:
1844 byte |= 0x40;
1845 break;
1846
1847 case REG_SP:
1848 byte |= 0x80;
1849 break;
1850
1851 default:
1852 as_bad (_("Invalid register for post/pre increment."));
1853 break;
1854 }
1855
1856 f = frag_more (1);
1857 number_to_chars_bigendian (f, byte, 1);
1858 return 1;
1859 }
1860
7bfda7eb 1861 if (mode & (M6812_OP_IDX | M6812_OP_D_IDX_2))
60bcf0fa
NC
1862 {
1863 switch (op->reg1)
1864 {
1865 case REG_X:
1866 byte = 0;
1867 break;
1868
1869 case REG_Y:
1870 byte = 1;
1871 break;
1872
1873 case REG_SP:
1874 byte = 2;
1875 break;
1876
1877 case REG_PC:
1878 byte = 3;
1879 break;
1880
1881 default:
1882 as_bad (_("Invalid register."));
1883 break;
1884 }
1885 if (op->exp.X_op == O_constant)
1886 {
1887 if (!check_range (val, M6812_OP_IDX))
1888 {
1889 as_bad (_("Offset out of 16-bit range: %ld."), val);
1890 }
1891
1892 if (move_insn && !(val >= -16 && val <= 15))
1893 {
ae3e85dd 1894 as_bad (_("Offset out of 5-bit range for movw/movb insn: %ld."),
098f2ec3 1895 val);
60bcf0fa
NC
1896 return -1;
1897 }
1898
7bfda7eb 1899 if (val >= -16 && val <= 15 && !(mode & M6812_OP_D_IDX_2))
60bcf0fa
NC
1900 {
1901 byte = byte << 6;
1902 byte |= val & 0x1f;
1903 f = frag_more (1);
1904 number_to_chars_bigendian (f, byte, 1);
1905 return 1;
1906 }
7bfda7eb 1907 else if (val >= -256 && val <= 255 && !(mode & M6812_OP_D_IDX_2))
60bcf0fa
NC
1908 {
1909 byte = byte << 3;
1910 byte |= 0xe0;
1911 if (val < 0)
1912 byte |= 0x1;
1913 f = frag_more (2);
1914 number_to_chars_bigendian (f, byte, 1);
1915 number_to_chars_bigendian (f + 1, val & 0x0FF, 1);
1916 return 2;
1917 }
1918 else
1919 {
1920 byte = byte << 3;
7bfda7eb 1921 if (mode & M6812_OP_D_IDX_2)
60bcf0fa
NC
1922 byte |= 0xe3;
1923 else
1924 byte |= 0xe2;
1925
1926 f = frag_more (3);
1927 number_to_chars_bigendian (f, byte, 1);
1928 number_to_chars_bigendian (f + 1, val & 0x0FFFF, 2);
1929 return 3;
1930 }
1931 }
7bfda7eb
SC
1932 if (mode & M6812_OP_D_IDX_2)
1933 {
1934 byte = (byte << 3) | 0xe3;
1935 f = frag_more (1);
1936 number_to_chars_bigendian (f, byte, 1);
1937
1938 fixup16 (&op->exp, 0, 0);
1939 }
1940 else if (op->reg1 != REG_PC)
098f2ec3 1941 {
c9e03e8b
SC
1942 symbolS *sym;
1943 offsetT off;
1944
098f2ec3
KH
1945 f = frag_more (1);
1946 number_to_chars_bigendian (f, byte, 1);
c9e03e8b
SC
1947 sym = op->exp.X_add_symbol;
1948 off = op->exp.X_add_number;
1949 if (op->exp.X_op != O_symbol)
1950 {
1951 sym = make_expr_symbol (&op->exp);
1952 off = 0;
1953 }
28d39d1a
NC
1954 /* movb/movw cannot be relaxed. */
1955 if (move_insn)
1956 {
1957 byte <<= 6;
1958 number_to_chars_bigendian (f, byte, 1);
1959 fix_new (frag_now, f - frag_now->fr_literal, 1,
1960 sym, off, 0, BFD_RELOC_M68HC12_5B);
1961 return 1;
1962 }
1963 else
1964 {
1965 number_to_chars_bigendian (f, byte, 1);
1966 frag_var (rs_machine_dependent, 2, 2,
1967 ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_UNDF),
1968 sym, off, f);
1969 }
098f2ec3 1970 }
88051039 1971 else
098f2ec3
KH
1972 {
1973 f = frag_more (1);
28d39d1a
NC
1974 /* movb/movw cannot be relaxed. */
1975 if (move_insn)
1976 {
1977 byte <<= 6;
1978 number_to_chars_bigendian (f, byte, 1);
1979 fix_new (frag_now, f - frag_now->fr_literal, 1,
1980 op->exp.X_add_symbol, op->exp.X_add_number, 0, BFD_RELOC_M68HC12_5B);
1981 return 1;
1982 }
1983 else
1984 {
1985 number_to_chars_bigendian (f, byte, 1);
1986 frag_var (rs_machine_dependent, 2, 2,
1987 ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_UNDF),
1988 op->exp.X_add_symbol,
1989 op->exp.X_add_number, f);
1990 }
098f2ec3 1991 }
60bcf0fa
NC
1992 return 3;
1993 }
1994
7bfda7eb 1995 if (mode & (M6812_OP_REG | M6812_OP_D_IDX))
60bcf0fa 1996 {
7bfda7eb 1997 if (mode & M6812_OP_D_IDX)
60bcf0fa
NC
1998 {
1999 if (op->reg1 != REG_D)
2000 as_bad (_("Expecting register D for indexed indirect mode."));
2001 if (move_insn)
2002 as_bad (_("Indexed indirect mode is not allowed for movb/movw."));
2003
2004 byte = 0xE7;
2005 }
2006 else
2007 {
2008 switch (op->reg1)
2009 {
2010 case REG_A:
2011 byte = 0xE4;
2012 break;
2013
2014 case REG_B:
2015 byte = 0xE5;
2016 break;
2017
2018 default:
2019 as_bad (_("Invalid accumulator register."));
2020
2021 case REG_D:
2022 byte = 0xE6;
2023 break;
2024 }
2025 }
2026 switch (op->reg2)
2027 {
2028 case REG_X:
2029 break;
2030
2031 case REG_Y:
2032 byte |= (1 << 3);
2033 break;
2034
2035 case REG_SP:
2036 byte |= (2 << 3);
2037 break;
2038
2039 case REG_PC:
2040 byte |= (3 << 3);
2041 break;
2042
2043 default:
2044 as_bad (_("Invalid indexed register."));
2045 break;
2046 }
2047 f = frag_more (1);
2048 number_to_chars_bigendian (f, byte, 1);
2049 return 1;
2050 }
2051
2052 as_fatal (_("Addressing mode not implemented yet."));
2053 return 0;
2054}
2055
2056/* Assemble the 68HC12 register mode byte. */
2057static int
ca43c854 2058build_reg_mode (operand *op, int format)
60bcf0fa
NC
2059{
2060 unsigned char byte;
2061 char *f;
2062
2063 if (format & M6812_OP_SEX_MARKER
2064 && op->reg1 != REG_A && op->reg1 != REG_B && op->reg1 != REG_CCR)
2065 as_bad (_("Invalid source register for this instruction, use 'tfr'."));
2066 else if (op->reg1 == REG_NONE || op->reg1 == REG_PC)
2067 as_bad (_("Invalid source register."));
2068
2069 if (format & M6812_OP_SEX_MARKER
2070 && op->reg2 != REG_D
2071 && op->reg2 != REG_X && op->reg2 != REG_Y && op->reg2 != REG_SP)
2072 as_bad (_("Invalid destination register for this instruction, use 'tfr'."));
2073 else if (op->reg2 == REG_NONE || op->reg2 == REG_PC)
2074 as_bad (_("Invalid destination register."));
2075
2076 byte = (op->reg1 << 4) | (op->reg2);
2077 if (format & M6812_OP_EXG_MARKER)
2078 byte |= 0x80;
2079
2080 f = frag_more (1);
2081 number_to_chars_bigendian (f, byte, 1);
2082 return 1;
2083}
2084
2085/* build_insn takes a pointer to the opcode entry in the opcode table,
67c1ffbe 2086 the array of operand expressions and builds the corresponding instruction.
60bcf0fa
NC
2087 This operation only deals with non relative jumps insn (need special
2088 handling). */
2089static void
ca43c854
SC
2090build_insn (struct m68hc11_opcode *opcode, operand operands[],
2091 int nb_operands ATTRIBUTE_UNUSED)
60bcf0fa
NC
2092{
2093 int i;
2094 char *f;
60bcf0fa
NC
2095 long format;
2096 int move_insn = 0;
2097
2098 /* Put the page code instruction if there is one. */
2099 format = opcode->format;
e371935f 2100
e371935f 2101 if (format & M6811_OP_BRANCH)
c9e03e8b 2102 fix_new (frag_now, frag_now_fix (), 1,
e371935f
SC
2103 &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
2104
60bcf0fa
NC
2105 if (format & OP_EXTENDED)
2106 {
2107 int page_code;
2108
2109 f = m68hc11_new_insn (2);
2110 if (format & M6811_OP_PAGE2)
2111 page_code = M6811_OPCODE_PAGE2;
2112 else if (format & M6811_OP_PAGE3)
2113 page_code = M6811_OPCODE_PAGE3;
2114 else
2115 page_code = M6811_OPCODE_PAGE4;
2116
2117 number_to_chars_bigendian (f, page_code, 1);
2118 f++;
60bcf0fa
NC
2119 }
2120 else
2121 f = m68hc11_new_insn (1);
2122
2123 number_to_chars_bigendian (f, opcode->opcode, 1);
2124
2125 i = 0;
2126
2127 /* The 68HC12 movb and movw instructions are special. We have to handle
2128 them in a special way. */
2129 if (format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2))
2130 {
2131 move_insn = 1;
2132 if (format & M6812_OP_IDX)
2133 {
986c6f4b 2134 build_indexed_byte (&operands[0], format, 1);
60bcf0fa
NC
2135 i = 1;
2136 format &= ~M6812_OP_IDX;
2137 }
2138 if (format & M6812_OP_IDX_P2)
2139 {
986c6f4b 2140 build_indexed_byte (&operands[1], format, 1);
60bcf0fa
NC
2141 i = 0;
2142 format &= ~M6812_OP_IDX_P2;
2143 }
2144 }
2145
2146 if (format & (M6811_OP_DIRECT | M6811_OP_IMM8))
2147 {
60bcf0fa
NC
2148 fixup8 (&operands[i].exp,
2149 format & (M6811_OP_DIRECT | M6811_OP_IMM8 | M6812_OP_TRAP_ID),
2150 operands[i].mode);
2151 i++;
2152 }
7bfda7eb
SC
2153 else if (IS_CALL_SYMBOL (format) && nb_operands == 1)
2154 {
2155 format &= ~M6812_OP_PAGE;
2156 fixup24 (&operands[i].exp, format & M6811_OP_IND16,
2157 operands[i].mode);
2158 i++;
2159 }
60bcf0fa
NC
2160 else if (format & (M6811_OP_IMM16 | M6811_OP_IND16))
2161 {
7bfda7eb
SC
2162 fixup16 (&operands[i].exp,
2163 format & (M6811_OP_IMM16 | M6811_OP_IND16 | M6812_OP_PAGE),
60bcf0fa
NC
2164 operands[i].mode);
2165 i++;
2166 }
2167 else if (format & (M6811_OP_IX | M6811_OP_IY))
2168 {
2169 if ((format & M6811_OP_IX) && (operands[0].reg1 != REG_X))
2170 as_bad (_("Invalid indexed register, expecting register X."));
2171 if ((format & M6811_OP_IY) && (operands[0].reg1 != REG_Y))
2172 as_bad (_("Invalid indexed register, expecting register Y."));
2173
60bcf0fa
NC
2174 fixup8 (&operands[0].exp, M6811_OP_IX, operands[0].mode);
2175 i = 1;
2176 }
2177 else if (format &
7bfda7eb
SC
2178 (M6812_OP_IDX | M6812_OP_IDX_2 | M6812_OP_IDX_1
2179 | M6812_OP_D_IDX | M6812_OP_D_IDX_2))
60bcf0fa 2180 {
986c6f4b 2181 build_indexed_byte (&operands[i], format, move_insn);
60bcf0fa
NC
2182 i++;
2183 }
2184 else if (format & M6812_OP_REG && current_architecture & cpu6812)
2185 {
986c6f4b 2186 build_reg_mode (&operands[i], format);
60bcf0fa
NC
2187 i++;
2188 }
2189 if (format & M6811_OP_BITMASK)
2190 {
60bcf0fa
NC
2191 fixup8 (&operands[i].exp, M6811_OP_BITMASK, operands[i].mode);
2192 i++;
2193 }
2194 if (format & M6811_OP_JUMP_REL)
2195 {
60bcf0fa 2196 fixup8 (&operands[i].exp, M6811_OP_JUMP_REL, operands[i].mode);
60bcf0fa
NC
2197 }
2198 else if (format & M6812_OP_IND16_P2)
2199 {
60bcf0fa
NC
2200 fixup16 (&operands[1].exp, M6811_OP_IND16, operands[1].mode);
2201 }
7bfda7eb
SC
2202 if (format & M6812_OP_PAGE)
2203 {
2204 fixup8 (&operands[i].exp, M6812_OP_PAGE, operands[i].mode);
2205 }
60bcf0fa 2206}
60bcf0fa
NC
2207\f
2208/* Opcode identification and operand analysis. */
2209
2210/* find() gets a pointer to an entry in the opcode table. It must look at all
2211 opcodes with the same name and use the operands to choose the correct
2212 opcode. Returns the opcode pointer if there was a match and 0 if none. */
2213static struct m68hc11_opcode *
ca43c854 2214find (struct m68hc11_opcode_def *opc, operand operands[], int nb_operands)
60bcf0fa
NC
2215{
2216 int i, match, pos;
2217 struct m68hc11_opcode *opcode;
2218 struct m68hc11_opcode *op_indirect;
2219
2220 op_indirect = 0;
2221 opcode = opc->opcode;
2222
2223 /* Now search the opcode table table for one with operands
2224 that matches what we've got. We're only done if the operands matched so
2225 far AND there are no more to check. */
2226 for (pos = match = 0; match == 0 && pos < opc->nb_modes; pos++, opcode++)
2227 {
2228 int poss_indirect = 0;
2229 long format = opcode->format;
2230 int expect;
2231
2232 expect = 0;
2233 if (opcode->format & M6811_OP_MASK)
2234 expect++;
2235 if (opcode->format & M6811_OP_BITMASK)
2236 expect++;
2237 if (opcode->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
2238 expect++;
2239 if (opcode->format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2))
2240 expect++;
7bfda7eb
SC
2241 if ((opcode->format & M6812_OP_PAGE)
2242 && (!IS_CALL_SYMBOL (opcode->format) || nb_operands == 2))
2243 expect++;
60bcf0fa
NC
2244
2245 for (i = 0; expect == nb_operands && i < nb_operands; i++)
2246 {
2247 int mode = operands[i].mode;
2248
2249 if (mode & M6811_OP_IMM16)
2250 {
2251 if (format &
2252 (M6811_OP_IMM8 | M6811_OP_IMM16 | M6811_OP_BITMASK))
2253 continue;
2254 break;
2255 }
2256 if (mode == M6811_OP_DIRECT)
2257 {
2258 if (format & M6811_OP_DIRECT)
2259 continue;
2260
2261 /* If the operand is a page 0 operand, remember a
2262 possible <abs-16> addressing mode. We mark
2263 this and continue to check other operands. */
2264 if (format & M6811_OP_IND16
2265 && flag_strict_direct_addressing && op_indirect == 0)
2266 {
2267 poss_indirect = 1;
2268 continue;
2269 }
2270 break;
2271 }
2272 if (mode & M6811_OP_IND16)
2273 {
2274 if (i == 0 && (format & M6811_OP_IND16) != 0)
2275 continue;
7bfda7eb
SC
2276 if (i != 0 && (format & M6812_OP_PAGE) != 0)
2277 continue;
60bcf0fa
NC
2278 if (i != 0 && (format & M6812_OP_IND16_P2) != 0)
2279 continue;
2280 if (i == 0 && (format & M6811_OP_BITMASK))
2281 break;
2282 }
2283 if (mode & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
2284 {
2285 if (format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
2286 continue;
2287 }
2288 if (mode & M6812_OP_REG)
2289 {
df86943d
NC
2290 if (i == 0
2291 && (format & M6812_OP_REG)
2292 && (operands[i].reg2 == REG_NONE))
60bcf0fa 2293 continue;
df86943d
NC
2294 if (i == 0
2295 && (format & M6812_OP_REG)
2296 && (format & M6812_OP_REG_2)
2297 && (operands[i].reg2 != REG_NONE))
60bcf0fa 2298 continue;
df86943d
NC
2299 if (i == 0
2300 && (format & M6812_OP_IDX)
2301 && (operands[i].reg2 != REG_NONE))
2302 continue;
df86943d
NC
2303 if (i == 0
2304 && (format & M6812_OP_IDX)
60bcf0fa
NC
2305 && (format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2)))
2306 continue;
df86943d
NC
2307 if (i == 1
2308 && (format & M6812_OP_IDX_P2))
60bcf0fa
NC
2309 continue;
2310 break;
2311 }
2312 if (mode & M6812_OP_IDX)
2313 {
2314 if (format & M6811_OP_IX && operands[i].reg1 == REG_X)
2315 continue;
2316 if (format & M6811_OP_IY && operands[i].reg1 == REG_Y)
2317 continue;
2318 if (i == 0
2319 && format & (M6812_OP_IDX | M6812_OP_IDX_1 | M6812_OP_IDX_2)
2320 && (operands[i].reg1 == REG_X
2321 || operands[i].reg1 == REG_Y
2322 || operands[i].reg1 == REG_SP
2323 || operands[i].reg1 == REG_PC))
2324 continue;
2325 if (i == 1 && format & M6812_OP_IDX_P2)
2326 continue;
2327 }
7bfda7eb
SC
2328 if (mode & format & (M6812_OP_D_IDX | M6812_OP_D_IDX_2))
2329 {
2330 if (i == 0)
2331 continue;
2332 }
60bcf0fa
NC
2333 if (mode & M6812_AUTO_INC_DEC)
2334 {
2335 if (i == 0
2336 && format & (M6812_OP_IDX | M6812_OP_IDX_1 |
2337 M6812_OP_IDX_2))
2338 continue;
2339 if (i == 1 && format & M6812_OP_IDX_P2)
2340 continue;
2341 }
2342 break;
2343 }
2344 match = i == nb_operands;
2345
2346 /* Operands are ok but an operand uses page 0 addressing mode
2347 while the insn supports abs-16 mode. Keep a reference to this
2348 insns in case there is no insn supporting page 0 addressing. */
2349 if (match && poss_indirect)
2350 {
2351 op_indirect = opcode;
2352 match = 0;
2353 }
2354 if (match)
2355 break;
2356 }
2357
2358 /* Page 0 addressing is used but not supported by any insn.
2359 If absolute addresses are supported, we use that insn. */
2360 if (match == 0 && op_indirect)
2361 {
2362 opcode = op_indirect;
2363 match = 1;
2364 }
2365
2366 if (!match)
2367 {
2368 return (0);
2369 }
2370
2371 return opcode;
2372}
2373
60bcf0fa
NC
2374/* Find the real opcode and its associated operands. We use a progressive
2375 approach here. On entry, 'opc' points to the first opcode in the
2376 table that matches the opcode name in the source line. We try to
2377 isolate an operand, find a possible match in the opcode table.
2378 We isolate another operand if no match were found. The table 'operands'
2379 is filled while operands are recognized.
2380
2381 Returns the opcode pointer that matches the opcode name in the
2382 source line and the associated operands. */
2383static struct m68hc11_opcode *
ca43c854
SC
2384find_opcode (struct m68hc11_opcode_def *opc, operand operands[],
2385 int *nb_operands)
60bcf0fa
NC
2386{
2387 struct m68hc11_opcode *opcode;
2388 int i;
2389
2390 if (opc->max_operands == 0)
2391 {
2392 *nb_operands = 0;
2393 return opc->opcode;
2394 }
2395
2396 for (i = 0; i < opc->max_operands;)
2397 {
2398 int result;
2399
2400 result = get_operand (&operands[i], i, opc->format);
2401 if (result <= 0)
fafb6d17 2402 return 0;
60bcf0fa
NC
2403
2404 /* Special case where the bitmask of the bclr/brclr
2405 instructions is not introduced by #.
2406 Example: bclr 3,x $80. */
2407 if (i == 1 && (opc->format & M6811_OP_BITMASK)
2408 && (operands[i].mode & M6811_OP_IND16))
2409 {
2410 operands[i].mode = M6811_OP_IMM16;
2411 }
2412
2413 i += result;
2414 *nb_operands = i;
2415 if (i >= opc->min_operands)
2416 {
2417 opcode = find (opc, operands, i);
577300ce
SC
2418
2419 /* Another special case for 'call foo,page' instructions.
2420 Since we support 'call foo' and 'call foo,page' we must look
2421 if the optional page specification is present otherwise we will
2422 assemble immediately and treat the page spec as garbage. */
7bfda7eb
SC
2423 if (opcode && !(opcode->format & M6812_OP_PAGE))
2424 return opcode;
2425
2426 if (opcode && *input_line_pointer != ',')
fafb6d17 2427 return opcode;
60bcf0fa
NC
2428 }
2429
2430 if (*input_line_pointer == ',')
2431 input_line_pointer++;
2432 }
82efde3a 2433
60bcf0fa
NC
2434 return 0;
2435}
2436
2437#define M6812_XBCC_MARKER (M6812_OP_TBCC_MARKER \
2438 | M6812_OP_DBCC_MARKER \
2439 | M6812_OP_IBCC_MARKER)
60bcf0fa
NC
2440\f
2441/* Gas line assembler entry point. */
2442
2443/* This is the main entry point for the machine-dependent assembler. str
2444 points to a machine-dependent instruction. This function is supposed to
2445 emit the frags/bytes it assembles to. */
2446void
ca43c854 2447md_assemble (char *str)
60bcf0fa
NC
2448{
2449 struct m68hc11_opcode_def *opc;
2450 struct m68hc11_opcode *opcode;
2451
2452 unsigned char *op_start, *save;
2453 unsigned char *op_end;
2454 char name[20];
2455 int nlen = 0;
2456 operand operands[M6811_MAX_OPERANDS];
2457 int nb_operands;
2458 int branch_optimize = 0;
2459 int alias_id = -1;
2460
fafb6d17 2461 /* Drop leading whitespace. */
60bcf0fa
NC
2462 while (*str == ' ')
2463 str++;
2464
2465 /* Find the opcode end and get the opcode in 'name'. The opcode is forced
2466 lower case (the opcode table only has lower case op-codes). */
2467 for (op_start = op_end = (unsigned char *) (str);
2468 *op_end && nlen < 20 && !is_end_of_line[*op_end] && *op_end != ' ';
2469 op_end++)
2470 {
3882b010 2471 name[nlen] = TOLOWER (op_start[nlen]);
60bcf0fa
NC
2472 nlen++;
2473 }
2474 name[nlen] = 0;
2475
2476 if (nlen == 0)
2477 {
2478 as_bad (_("No instruction or missing opcode."));
2479 return;
2480 }
2481
2482 /* Find the opcode definition given its name. */
2483 opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash, name);
2484
2485 /* If it's not recognized, look for 'jbsr' and 'jbxx'. These are
2486 pseudo insns for relative branch. For these branchs, we always
2487 optimize them (turned into absolute branchs) even if --short-branchs
2488 is given. */
2489 if (opc == NULL && name[0] == 'j' && name[1] == 'b')
2490 {
2491 opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash, &name[1]);
2492 if (opc
2493 && (!(opc->format & M6811_OP_JUMP_REL)
2494 || (opc->format & M6811_OP_BITMASK)))
2495 opc = 0;
2496 if (opc)
2497 branch_optimize = 1;
2498 }
2499
2500 /* The following test should probably be removed. This is not conform
2501 to Motorola assembler specs. */
2502 if (opc == NULL && flag_mri)
2503 {
2504 if (*op_end == ' ' || *op_end == '\t')
2505 {
2506 while (*op_end == ' ' || *op_end == '\t')
2507 op_end++;
2508
2509 if (nlen < 19
2510 && (*op_end &&
2511 (is_end_of_line[op_end[1]]
2512 || op_end[1] == ' ' || op_end[1] == '\t'
3882b010 2513 || !ISALNUM (op_end[1])))
60bcf0fa
NC
2514 && (*op_end == 'a' || *op_end == 'b'
2515 || *op_end == 'A' || *op_end == 'B'
2516 || *op_end == 'd' || *op_end == 'D'
2517 || *op_end == 'x' || *op_end == 'X'
2518 || *op_end == 'y' || *op_end == 'Y'))
2519 {
3882b010 2520 name[nlen++] = TOLOWER (*op_end++);
60bcf0fa
NC
2521 name[nlen] = 0;
2522 opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash,
2523 name);
2524 }
2525 }
2526 }
2527
2528 /* Identify a possible instruction alias. There are some on the
986c6f4b 2529 68HC12 to emulate a few 68HC11 instructions. */
60bcf0fa
NC
2530 if (opc == NULL && (current_architecture & cpu6812))
2531 {
2532 int i;
2533
2534 for (i = 0; i < m68hc12_num_alias; i++)
2535 if (strcmp (m68hc12_alias[i].name, name) == 0)
2536 {
2537 alias_id = i;
2538 break;
2539 }
2540 }
2541 if (opc == NULL && alias_id < 0)
2542 {
2543 as_bad (_("Opcode `%s' is not recognized."), name);
2544 return;
2545 }
2546 save = input_line_pointer;
2547 input_line_pointer = op_end;
2548
2549 if (opc)
2550 {
2551 opc->used++;
2552 opcode = find_opcode (opc, operands, &nb_operands);
2553 }
2554 else
2555 opcode = 0;
2556
2557 if ((opcode || alias_id >= 0) && !flag_mri)
2558 {
2559 char *p = input_line_pointer;
2560
2561 while (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r')
2562 p++;
2563
2564 if (*p != '\n' && *p)
2565 as_bad (_("Garbage at end of instruction: `%s'."), p);
2566 }
2567
2568 input_line_pointer = save;
2569
2570 if (alias_id >= 0)
2571 {
2572 char *f = m68hc11_new_insn (m68hc12_alias[alias_id].size);
fafb6d17 2573
60bcf0fa
NC
2574 number_to_chars_bigendian (f, m68hc12_alias[alias_id].code1, 1);
2575 if (m68hc12_alias[alias_id].size > 1)
2576 number_to_chars_bigendian (f + 1, m68hc12_alias[alias_id].code2, 1);
2577
2578 return;
2579 }
2580
2581 /* Opcode is known but does not have valid operands. Print out the
2582 syntax for this opcode. */
2583 if (opcode == 0)
2584 {
2585 if (flag_print_insn_syntax)
2586 print_insn_format (name);
2587
2588 as_bad (_("Invalid operand for `%s'"), name);
2589 return;
2590 }
2591
2592 /* Treat dbeq/ibeq/tbeq instructions in a special way. The branch is
2593 relative and must be in the range -256..255 (9-bits). */
2594 if ((opcode->format & M6812_XBCC_MARKER)
2595 && (opcode->format & M6811_OP_JUMP_REL))
27302d63 2596 build_dbranch_insn (opcode, operands, nb_operands, branch_optimize);
60bcf0fa
NC
2597
2598 /* Relative jumps instructions are taken care of separately. We have to make
2599 sure that the relative branch is within the range -128..127. If it's out
2600 of range, the instructions are changed into absolute instructions.
2601 This is not supported for the brset and brclr instructions. */
2602 else if ((opcode->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
2603 && !(opcode->format & M6811_OP_BITMASK))
2604 build_jump_insn (opcode, operands, nb_operands, branch_optimize);
2605 else
2606 build_insn (opcode, operands, nb_operands);
2607}
eb086b59
SC
2608
2609\f
2610/* Pseudo op to control the ELF flags. */
2611static void
ca43c854 2612s_m68hc11_mode (int x ATTRIBUTE_UNUSED)
eb086b59
SC
2613{
2614 char *name = input_line_pointer, ch;
2615
2616 while (!is_end_of_line[(unsigned char) *input_line_pointer])
2617 input_line_pointer++;
2618 ch = *input_line_pointer;
2619 *input_line_pointer = '\0';
2620
2621 if (strcmp (name, "mshort") == 0)
2622 {
2623 elf_flags &= ~E_M68HC11_I32;
2624 }
2625 else if (strcmp (name, "mlong") == 0)
2626 {
2627 elf_flags |= E_M68HC11_I32;
2628 }
2629 else if (strcmp (name, "mshort-double") == 0)
2630 {
2631 elf_flags &= ~E_M68HC11_F64;
2632 }
2633 else if (strcmp (name, "mlong-double") == 0)
2634 {
2635 elf_flags |= E_M68HC11_F64;
2636 }
2637 else
2638 {
2639 as_warn (_("Invalid mode: %s\n"), name);
2640 }
2641 *input_line_pointer = ch;
2642 demand_empty_rest_of_line ();
2643}
2644
2645/* Mark the symbols with STO_M68HC12_FAR to indicate the functions
2646 are using 'rtc' for returning. It is necessary to use 'call'
2647 to invoke them. This is also used by the debugger to correctly
2648 find the stack frame. */
2649static void
ca43c854 2650s_m68hc11_mark_symbol (int mark)
eb086b59
SC
2651{
2652 char *name;
2653 int c;
2654 symbolS *symbolP;
2655 asymbol *bfdsym;
2656 elf_symbol_type *elfsym;
2657
2658 do
2659 {
2660 name = input_line_pointer;
2661 c = get_symbol_end ();
2662 symbolP = symbol_find_or_make (name);
2663 *input_line_pointer = c;
2664
2665 SKIP_WHITESPACE ();
2666
2667 bfdsym = symbol_get_bfdsym (symbolP);
2668 elfsym = elf_symbol_from (bfd_asymbol_bfd (bfdsym), bfdsym);
2669
2670 assert (elfsym);
2671
2672 /* Mark the symbol far (using rtc for function return). */
2673 elfsym->internal_elf_sym.st_other |= mark;
2674
2675 if (c == ',')
2676 {
2677 input_line_pointer ++;
2678
2679 SKIP_WHITESPACE ();
2680
2681 if (*input_line_pointer == '\n')
2682 c = '\n';
2683 }
2684 }
2685 while (c == ',');
2686
2687 demand_empty_rest_of_line ();
2688}
e371935f
SC
2689
2690static void
ca43c854 2691s_m68hc11_relax (int ignore ATTRIBUTE_UNUSED)
e371935f
SC
2692{
2693 expressionS ex;
2694
2695 expression (&ex);
2696
2697 if (ex.X_op != O_symbol || ex.X_add_number != 0)
2698 {
2699 as_bad (_("bad .relax format"));
2700 ignore_rest_of_line ();
2701 return;
2702 }
2703
12a99586 2704 fix_new_exp (frag_now, frag_now_fix (), 2, &ex, 1,
e371935f
SC
2705 BFD_RELOC_M68HC11_RL_GROUP);
2706
2707 demand_empty_rest_of_line ();
2708}
2709
60bcf0fa
NC
2710\f
2711/* Relocation, relaxation and frag conversions. */
e371935f
SC
2712
2713/* PC-relative offsets are relative to the start of the
2714 next instruction. That is, the address of the offset, plus its
2715 size, since the offset is always the last part of the insn. */
60bcf0fa 2716long
ca43c854 2717md_pcrel_from (fixS *fixP)
60bcf0fa 2718{
e371935f 2719 if (fixP->fx_r_type == BFD_RELOC_M68HC11_RL_JUMP)
60bcf0fa
NC
2720 return 0;
2721
e371935f 2722 return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
60bcf0fa
NC
2723}
2724
2725/* If while processing a fixup, a reloc really needs to be created
2726 then it is done here. */
2727arelent *
ca43c854 2728tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
60bcf0fa
NC
2729{
2730 arelent *reloc;
2731
2732 reloc = (arelent *) xmalloc (sizeof (arelent));
2733 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
2734 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
2735 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
2736 if (fixp->fx_r_type == 0)
2737 reloc->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_16);
2738 else
2739 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
2740 if (reloc->howto == (reloc_howto_type *) NULL)
2741 {
2742 as_bad_where (fixp->fx_file, fixp->fx_line,
2743 _("Relocation %d is not supported by object file format."),
2744 (int) fixp->fx_r_type);
2745 return NULL;
2746 }
2747
a161fe53
AM
2748 /* Since we use Rel instead of Rela, encode the vtable entry to be
2749 used in the relocation's section offset. */
2750 if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
2751 reloc->address = fixp->fx_offset;
2752
2753 reloc->addend = 0;
60bcf0fa
NC
2754 return reloc;
2755}
2756
c9e03e8b
SC
2757/* We need a port-specific relaxation function to cope with sym2 - sym1
2758 relative expressions with both symbols in the same segment (but not
2759 necessarily in the same frag as this insn), for example:
2760 ldab sym2-(sym1-2),pc
2761 sym1:
2762 The offset can be 5, 9 or 16 bits long. */
2763
2764long
ca43c854
SC
2765m68hc11_relax_frag (segT seg ATTRIBUTE_UNUSED, fragS *fragP,
2766 long stretch ATTRIBUTE_UNUSED)
c9e03e8b
SC
2767{
2768 long growth;
2769 offsetT aim = 0;
2770 symbolS *symbolP;
2771 const relax_typeS *this_type;
2772 const relax_typeS *start_type;
2773 relax_substateT next_state;
2774 relax_substateT this_state;
2775 const relax_typeS *table = TC_GENERIC_RELAX_TABLE;
2776
2777 /* We only have to cope with frags as prepared by
2778 md_estimate_size_before_relax. The STATE_BITS16 case may geet here
2779 because of the different reasons that it's not relaxable. */
2780 switch (fragP->fr_subtype)
2781 {
75538612 2782 case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS16):
c9e03e8b
SC
2783 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16):
2784 /* When we get to this state, the frag won't grow any more. */
2785 return 0;
2786
75538612 2787 case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS5):
c9e03e8b 2788 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS5):
75538612 2789 case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS9):
c9e03e8b
SC
2790 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9):
2791 if (fragP->fr_symbol == NULL
2792 || S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
2793 as_fatal (_("internal inconsistency problem in %s: fr_symbol %lx"),
2794 __FUNCTION__, (long) fragP->fr_symbol);
2795 symbolP = fragP->fr_symbol;
2796 if (symbol_resolved_p (symbolP))
2797 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
2798 __FUNCTION__);
2799 aim = S_GET_VALUE (symbolP);
2800 break;
2801
2802 default:
2803 as_fatal (_("internal inconsistency problem in %s: fr_subtype %d"),
2804 __FUNCTION__, fragP->fr_subtype);
2805 }
2806
2807 /* The rest is stolen from relax_frag. There's no obvious way to
2808 share the code, but fortunately no requirement to keep in sync as
2809 long as fragP->fr_symbol does not have its segment changed. */
2810
2811 this_state = fragP->fr_subtype;
2812 start_type = this_type = table + this_state;
2813
2814 if (aim < 0)
2815 {
2816 /* Look backwards. */
2817 for (next_state = this_type->rlx_more; next_state;)
2818 if (aim >= this_type->rlx_backward)
2819 next_state = 0;
2820 else
2821 {
2822 /* Grow to next state. */
2823 this_state = next_state;
2824 this_type = table + this_state;
2825 next_state = this_type->rlx_more;
2826 }
2827 }
2828 else
2829 {
2830 /* Look forwards. */
2831 for (next_state = this_type->rlx_more; next_state;)
2832 if (aim <= this_type->rlx_forward)
2833 next_state = 0;
2834 else
2835 {
2836 /* Grow to next state. */
2837 this_state = next_state;
2838 this_type = table + this_state;
2839 next_state = this_type->rlx_more;
2840 }
2841 }
2842
2843 growth = this_type->rlx_length - start_type->rlx_length;
2844 if (growth != 0)
2845 fragP->fr_subtype = this_state;
2846 return growth;
2847}
2848
60bcf0fa 2849void
ca43c854
SC
2850md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, asection *sec ATTRIBUTE_UNUSED,
2851 fragS *fragP)
60bcf0fa
NC
2852{
2853 fixS *fixp;
88051039 2854 long value;
60bcf0fa
NC
2855 long disp;
2856 char *buffer_address = fragP->fr_literal;
2857
2858 /* Address in object code of the displacement. */
2859 register int object_address = fragP->fr_fix + fragP->fr_address;
2860
2861 buffer_address += fragP->fr_fix;
2862
2863 /* The displacement of the address, from current location. */
ac62c346 2864 value = S_GET_VALUE (fragP->fr_symbol);
88051039 2865 disp = (value + fragP->fr_offset) - object_address;
60bcf0fa
NC
2866
2867 switch (fragP->fr_subtype)
2868 {
2869 case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE):
2870 fragP->fr_opcode[1] = disp;
2871 break;
2872
2873 case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD):
2874 /* This relax is only for bsr and bra. */
2875 assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
2876 || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
2877 || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
2878
2879 fragP->fr_opcode[0] = convert_branch (fragP->fr_opcode[0]);
2880
2881 fix_new (fragP, fragP->fr_fix - 1, 2,
2882 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
2883 fragP->fr_fix += 1;
2884 break;
2885
2886 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_BYTE):
2887 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_BYTE):
2888 fragP->fr_opcode[1] = disp;
2889 break;
2890
2891 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_WORD):
2892 /* Invert branch. */
2893 fragP->fr_opcode[0] ^= 1;
fafb6d17 2894 fragP->fr_opcode[1] = 3; /* Branch offset. */
60bcf0fa
NC
2895 buffer_address[0] = M6811_JMP;
2896 fix_new (fragP, fragP->fr_fix + 1, 2,
2897 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
2898 fragP->fr_fix += 3;
2899 break;
2900
2901 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_WORD):
2902 /* Translate branch into a long branch. */
2903 fragP->fr_opcode[1] = fragP->fr_opcode[0];
2904 fragP->fr_opcode[0] = M6811_OPCODE_PAGE2;
2905
2906 fixp = fix_new (fragP, fragP->fr_fix, 2,
2907 fragP->fr_symbol, fragP->fr_offset, 1,
2908 BFD_RELOC_16_PCREL);
2909 fixp->fx_pcrel_adjust = 2;
2910 fragP->fr_fix += 2;
2911 break;
2912
75538612
SC
2913 case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS5):
2914 if (fragP->fr_symbol != 0
c9e03e8b
SC
2915 && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
2916 value = disp;
75538612
SC
2917 /* fall through */
2918
2919 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS5):
88051039 2920 fragP->fr_opcode[0] = fragP->fr_opcode[0] << 6;
c9e03e8b 2921 fragP->fr_opcode[0] |= value & 0x1f;
60bcf0fa
NC
2922 break;
2923
75538612
SC
2924 case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS9):
2925 /* For a PC-relative offset, use the displacement with a -1 correction
2926 to take into account the additional byte of the insn. */
2927 if (fragP->fr_symbol != 0
c9e03e8b 2928 && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
75538612
SC
2929 value = disp - 1;
2930 /* fall through */
2931
2932 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9):
60bcf0fa
NC
2933 fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3);
2934 fragP->fr_opcode[0] |= 0xE0;
c9e03e8b
SC
2935 fragP->fr_opcode[0] |= (value >> 8) & 1;
2936 fragP->fr_opcode[1] = value;
60bcf0fa
NC
2937 fragP->fr_fix += 1;
2938 break;
2939
75538612 2940 case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS16):
60bcf0fa
NC
2941 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16):
2942 fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3);
88051039 2943 fragP->fr_opcode[0] |= 0xe2;
c9e03e8b
SC
2944 if ((fragP->fr_opcode[0] & 0x0ff) == 0x0fa
2945 && fragP->fr_symbol != 0
2946 && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
098f2ec3
KH
2947 {
2948 fixp = fix_new (fragP, fragP->fr_fix, 2,
2949 fragP->fr_symbol, fragP->fr_offset,
2950 1, BFD_RELOC_16_PCREL);
098f2ec3 2951 }
88051039 2952 else
098f2ec3
KH
2953 {
2954 fix_new (fragP, fragP->fr_fix, 2,
2955 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
2956 }
88051039 2957 fragP->fr_fix += 2;
60bcf0fa
NC
2958 break;
2959
2960 case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_BYTE):
2961 if (disp < 0)
2962 fragP->fr_opcode[0] |= 0x10;
2963
2964 fragP->fr_opcode[1] = disp & 0x0FF;
2965 break;
2966
2967 case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_WORD):
2968 /* Invert branch. */
2969 fragP->fr_opcode[0] ^= 0x20;
2970 fragP->fr_opcode[1] = 3; /* Branch offset. */
2971 buffer_address[0] = M6812_JMP;
2972 fix_new (fragP, fragP->fr_fix + 1, 2,
2973 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
2974 fragP->fr_fix += 3;
2975 break;
2976
2977 default:
2978 break;
2979 }
2980}
2981
dbb8ad49
SC
2982/* On an ELF system, we can't relax a weak symbol. The weak symbol
2983 can be overridden at final link time by a non weak symbol. We can
2984 relax externally visible symbol because there is no shared library
2985 and such symbol can't be overridden (unless they are weak). */
d8273f3b 2986static int
ca43c854 2987relaxable_symbol (symbolS *symbol)
d8273f3b 2988{
dbb8ad49 2989 return ! S_IS_WEAK (symbol);
d8273f3b
SC
2990}
2991
60bcf0fa
NC
2992/* Force truly undefined symbols to their maximum size, and generally set up
2993 the frag list to be relaxed. */
2994int
ca43c854 2995md_estimate_size_before_relax (fragS *fragP, asection *segment)
60bcf0fa 2996{
606ab118
AM
2997 if (RELAX_LENGTH (fragP->fr_subtype) == STATE_UNDF)
2998 {
2999 if (S_GET_SEGMENT (fragP->fr_symbol) != segment
577300ce
SC
3000 || !relaxable_symbol (fragP->fr_symbol)
3001 || (segment != absolute_section
3002 && RELAX_STATE (fragP->fr_subtype) == STATE_INDEXED_OFFSET))
606ab118
AM
3003 {
3004 /* Non-relaxable cases. */
3005 int old_fr_fix;
3006 char *buffer_address;
60bcf0fa 3007
606ab118
AM
3008 old_fr_fix = fragP->fr_fix;
3009 buffer_address = fragP->fr_fix + fragP->fr_literal;
60bcf0fa 3010
606ab118
AM
3011 switch (RELAX_STATE (fragP->fr_subtype))
3012 {
3013 case STATE_PC_RELATIVE:
3014
3015 /* This relax is only for bsr and bra. */
3016 assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
3017 || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
3018 || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
3019
3020 if (flag_fixed_branchs)
3021 as_bad_where (fragP->fr_file, fragP->fr_line,
3022 _("bra or bsr with undefined symbol."));
3023
3024 /* The symbol is undefined or in a separate section.
3025 Turn bra into a jmp and bsr into a jsr. The insn
3026 becomes 3 bytes long (instead of 2). A fixup is
3027 necessary for the unresolved symbol address. */
3028 fragP->fr_opcode[0] = convert_branch (fragP->fr_opcode[0]);
3029
13283e2d 3030 fix_new (fragP, fragP->fr_fix - 1, 2, fragP->fr_symbol,
606ab118 3031 fragP->fr_offset, 0, BFD_RELOC_16);
13283e2d 3032 fragP->fr_fix++;
606ab118 3033 break;
60bcf0fa 3034
606ab118
AM
3035 case STATE_CONDITIONAL_BRANCH:
3036 assert (current_architecture & cpu6811);
60bcf0fa 3037
606ab118
AM
3038 fragP->fr_opcode[0] ^= 1; /* Reverse sense of branch. */
3039 fragP->fr_opcode[1] = 3; /* Skip next jmp insn (3 bytes). */
60bcf0fa 3040
606ab118
AM
3041 /* Don't use fr_opcode[2] because this may be
3042 in a different frag. */
3043 buffer_address[0] = M6811_JMP;
60bcf0fa 3044
606ab118
AM
3045 fragP->fr_fix++;
3046 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
3047 fragP->fr_offset, 0, BFD_RELOC_16);
3048 fragP->fr_fix += 2;
3049 break;
60bcf0fa 3050
606ab118
AM
3051 case STATE_INDEXED_OFFSET:
3052 assert (current_architecture & cpu6812);
60bcf0fa 3053
c9e03e8b
SC
3054 if (fragP->fr_symbol
3055 && S_GET_SEGMENT (fragP->fr_symbol) == absolute_section)
3056 {
3057 fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_OFFSET,
3058 STATE_BITS5);
3059 /* Return the size of the variable part of the frag. */
3060 return md_relax_table[fragP->fr_subtype].rlx_length;
3061 }
3062 else
3063 {
3064 /* Switch the indexed operation to 16-bit mode. */
3065 fragP->fr_opcode[0] = fragP->fr_opcode[0] << 3;
3066 fragP->fr_opcode[0] |= 0xe2;
3067 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
3068 fragP->fr_offset, 0, BFD_RELOC_16);
3069 fragP->fr_fix += 2;
3070 }
606ab118 3071 break;
60bcf0fa 3072
75538612
SC
3073 case STATE_INDEXED_PCREL:
3074 assert (current_architecture & cpu6812);
3075
3076 if (fragP->fr_symbol
3077 && S_GET_SEGMENT (fragP->fr_symbol) == absolute_section)
3078 {
3079 fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_PCREL,
3080 STATE_BITS5);
3081 /* Return the size of the variable part of the frag. */
3082 return md_relax_table[fragP->fr_subtype].rlx_length;
3083 }
3084 else
3085 {
3086 fixS* fixp;
3087
3088 fragP->fr_opcode[0] = fragP->fr_opcode[0] << 3;
3089 fragP->fr_opcode[0] |= 0xe2;
3090 fixp = fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
3091 fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
3092 fragP->fr_fix += 2;
3093 }
3094 break;
3095
606ab118
AM
3096 case STATE_XBCC_BRANCH:
3097 assert (current_architecture & cpu6812);
3098
3099 fragP->fr_opcode[0] ^= 0x20; /* Reverse sense of branch. */
3100 fragP->fr_opcode[1] = 3; /* Skip next jmp insn (3 bytes). */
60bcf0fa 3101
606ab118
AM
3102 /* Don't use fr_opcode[2] because this may be
3103 in a different frag. */
3104 buffer_address[0] = M6812_JMP;
3105
3106 fragP->fr_fix++;
3107 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
3108 fragP->fr_offset, 0, BFD_RELOC_16);
3109 fragP->fr_fix += 2;
3110 break;
60bcf0fa 3111
606ab118
AM
3112 case STATE_CONDITIONAL_BRANCH_6812:
3113 assert (current_architecture & cpu6812);
3114
3115 /* Translate into a lbcc branch. */
3116 fragP->fr_opcode[1] = fragP->fr_opcode[0];
3117 fragP->fr_opcode[0] = M6811_OPCODE_PAGE2;
3118
3119 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
e371935f 3120 fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
606ab118
AM
3121 fragP->fr_fix += 2;
3122 break;
3123
3124 default:
3125 as_fatal (_("Subtype %d is not recognized."), fragP->fr_subtype);
3126 }
60bcf0fa 3127 frag_wane (fragP);
60bcf0fa 3128
606ab118
AM
3129 /* Return the growth in the fixed part of the frag. */
3130 return fragP->fr_fix - old_fr_fix;
3131 }
60bcf0fa 3132
606ab118
AM
3133 /* Relaxable cases. */
3134 switch (RELAX_STATE (fragP->fr_subtype))
60bcf0fa 3135 {
606ab118
AM
3136 case STATE_PC_RELATIVE:
3137 /* This relax is only for bsr and bra. */
3138 assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
3139 || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
3140 || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
3141
3142 fragP->fr_subtype = ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE);
3143 break;
3144
3145 case STATE_CONDITIONAL_BRANCH:
3146 assert (current_architecture & cpu6811);
3147
3148 fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH,
3149 STATE_BYTE);
3150 break;
3151
3152 case STATE_INDEXED_OFFSET:
3153 assert (current_architecture & cpu6812);
3154
60bcf0fa
NC
3155 fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_OFFSET,
3156 STATE_BITS5);
606ab118 3157 break;
60bcf0fa 3158
75538612
SC
3159 case STATE_INDEXED_PCREL:
3160 assert (current_architecture & cpu6812);
3161
3162 fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_PCREL,
3163 STATE_BITS5);
3164 break;
3165
606ab118
AM
3166 case STATE_XBCC_BRANCH:
3167 assert (current_architecture & cpu6812);
60bcf0fa 3168
60bcf0fa 3169 fragP->fr_subtype = ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_BYTE);
606ab118 3170 break;
60bcf0fa 3171
606ab118
AM
3172 case STATE_CONDITIONAL_BRANCH_6812:
3173 assert (current_architecture & cpu6812);
60bcf0fa 3174
60bcf0fa
NC
3175 fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812,
3176 STATE_BYTE);
606ab118 3177 break;
60bcf0fa 3178 }
60bcf0fa
NC
3179 }
3180
606ab118
AM
3181 if (fragP->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))
3182 as_fatal (_("Subtype %d is not recognized."), fragP->fr_subtype);
3183
3184 /* Return the size of the variable part of the frag. */
3185 return md_relax_table[fragP->fr_subtype].rlx_length;
60bcf0fa
NC
3186}
3187
e371935f
SC
3188/* See whether we need to force a relocation into the output file. */
3189int
ca43c854 3190tc_m68hc11_force_relocation (fixS *fixP)
e371935f 3191{
ae6063d4
AM
3192 if (fixP->fx_r_type == BFD_RELOC_M68HC11_RL_GROUP)
3193 return 1;
a161fe53 3194
ae6063d4 3195 return generic_force_reloc (fixP);
e371935f
SC
3196}
3197
3198/* Here we decide which fixups can be adjusted to make them relative
3199 to the beginning of the section instead of the symbol. Basically
3200 we need to make sure that the linker relaxation is done
3201 correctly, so in some cases we force the original symbol to be
3202 used. */
3203int
ca43c854 3204tc_m68hc11_fix_adjustable (fixS *fixP)
e371935f 3205{
e371935f
SC
3206 switch (fixP->fx_r_type)
3207 {
3208 /* For the linker relaxation to work correctly, these relocs
3209 need to be on the symbol itself. */
3210 case BFD_RELOC_16:
e371935f
SC
3211 case BFD_RELOC_M68HC11_RL_JUMP:
3212 case BFD_RELOC_M68HC11_RL_GROUP:
3213 case BFD_RELOC_VTABLE_INHERIT:
3214 case BFD_RELOC_VTABLE_ENTRY:
577300ce 3215 case BFD_RELOC_32:
2d94a61a
SC
3216
3217 /* The memory bank addressing translation also needs the original
3218 symbol. */
577300ce 3219 case BFD_RELOC_M68HC11_LO16:
2d94a61a
SC
3220 case BFD_RELOC_M68HC11_PAGE:
3221 case BFD_RELOC_M68HC11_24:
e371935f
SC
3222 return 0;
3223
e371935f
SC
3224 default:
3225 return 1;
3226 }
3227}
3228
94f592af 3229void
ca43c854 3230md_apply_fix3 (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
60bcf0fa
NC
3231{
3232 char *where;
94f592af 3233 long value = * valP;
60bcf0fa
NC
3234 int op_type;
3235
94f592af
NC
3236 if (fixP->fx_addsy == (symbolS *) NULL)
3237 fixP->fx_done = 1;
3238
a161fe53
AM
3239 /* We don't actually support subtracting a symbol. */
3240 if (fixP->fx_subsy != (symbolS *) NULL)
3241 as_bad_where (fixP->fx_file, fixP->fx_line, _("Expression too complex."));
60bcf0fa 3242
94f592af 3243 op_type = fixP->fx_r_type;
60bcf0fa
NC
3244
3245 /* Patch the instruction with the resolved operand. Elf relocation
3246 info will also be generated to take care of linker/loader fixups.
3247 The 68HC11 addresses only 64Kb, we are only concerned by 8 and 16-bit
3248 relocs. BFD_RELOC_8 is basically used for .page0 access (the linker
3249 will warn for overflows). BFD_RELOC_8_PCREL should not be generated
3250 because it's either resolved or turned out into non-relative insns (see
3251 relax table, bcc, bra, bsr transformations)
3252
3253 The BFD_RELOC_32 is necessary for the support of --gstabs. */
94f592af 3254 where = fixP->fx_frag->fr_literal + fixP->fx_where;
60bcf0fa 3255
94f592af 3256 switch (fixP->fx_r_type)
60bcf0fa
NC
3257 {
3258 case BFD_RELOC_32:
3259 bfd_putb32 ((bfd_vma) value, (unsigned char *) where);
3260 break;
3261
7bfda7eb
SC
3262 case BFD_RELOC_24:
3263 case BFD_RELOC_M68HC11_24:
3264 bfd_putb16 ((bfd_vma) (value & 0x0ffff), (unsigned char *) where);
3265 ((bfd_byte*) where)[2] = ((value >> 16) & 0x0ff);
3266 break;
3267
60bcf0fa
NC
3268 case BFD_RELOC_16:
3269 case BFD_RELOC_16_PCREL:
7bfda7eb 3270 case BFD_RELOC_M68HC11_LO16:
60bcf0fa
NC
3271 bfd_putb16 ((bfd_vma) value, (unsigned char *) where);
3272 if (value < -65537 || value > 65535)
94f592af 3273 as_bad_where (fixP->fx_file, fixP->fx_line,
60bcf0fa
NC
3274 _("Value out of 16-bit range."));
3275 break;
3276
3277 case BFD_RELOC_M68HC11_HI8:
3278 value = value >> 8;
fafb6d17 3279 /* Fall through. */
60bcf0fa
NC
3280
3281 case BFD_RELOC_M68HC11_LO8:
3282 case BFD_RELOC_8:
7bfda7eb 3283 case BFD_RELOC_M68HC11_PAGE:
60bcf0fa
NC
3284 ((bfd_byte *) where)[0] = (bfd_byte) value;
3285 break;
3286
3287 case BFD_RELOC_8_PCREL:
60bcf0fa
NC
3288 ((bfd_byte *) where)[0] = (bfd_byte) value;
3289
3290 if (value < -128 || value > 127)
94f592af 3291 as_bad_where (fixP->fx_file, fixP->fx_line,
60bcf0fa
NC
3292 _("Value %ld too large for 8-bit PC-relative branch."),
3293 value);
3294 break;
3295
3296 case BFD_RELOC_M68HC11_3B:
3297 if (value <= 0 || value > 8)
94f592af 3298 as_bad_where (fixP->fx_file, fixP->fx_line,
60bcf0fa
NC
3299 _("Auto increment/decrement offset '%ld' is out of range."),
3300 value);
3301 if (where[0] & 0x8)
3302 value = 8 - value;
3303 else
3304 value--;
3305
3306 where[0] = where[0] | (value & 0x07);
3307 break;
3308
28d39d1a
NC
3309 case BFD_RELOC_M68HC12_5B:
3310 if (value < -16 || value > 15)
3311 as_bad_where (fixP->fx_file, fixP->fx_line,
3312 _("Offset out of 5-bit range for movw/movb insn: %ld"),
3313 value);
3314 if (value >= 0)
3315 where[0] |= value;
3316 else
3317 where[0] |= (0x10 | (16 + value));
3318 break;
3319
e371935f
SC
3320 case BFD_RELOC_M68HC11_RL_JUMP:
3321 case BFD_RELOC_M68HC11_RL_GROUP:
3322 case BFD_RELOC_VTABLE_INHERIT:
3323 case BFD_RELOC_VTABLE_ENTRY:
3324 fixP->fx_done = 0;
3325 return;
3326
60bcf0fa
NC
3327 default:
3328 as_fatal (_("Line %d: unknown relocation type: 0x%x."),
94f592af 3329 fixP->fx_line, fixP->fx_r_type);
60bcf0fa 3330 }
60bcf0fa 3331}
eb086b59
SC
3332
3333/* Set the ELF specific flags. */
3334void
ca43c854 3335m68hc11_elf_final_processing (void)
eb086b59 3336{
d01030e6
SC
3337 if (current_architecture & cpu6812s)
3338 elf_flags |= EF_M68HCS12_MACH;
eb086b59
SC
3339 elf_elfheader (stdoutput)->e_flags &= ~EF_M68HC11_ABI;
3340 elf_elfheader (stdoutput)->e_flags |= elf_flags;
3341}