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