]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gas/config/tc-m68hc11.c
Automatic date update in version.in
[thirdparty/binutils-gdb.git] / gas / config / tc-m68hc11.c
CommitLineData
60bcf0fa 1/* tc-m68hc11.c -- Assembler code for the Motorola 68HC11 & 68HC12.
fd67aa11 2 Copyright (C) 1999-2024 Free Software Foundation, Inc.
7bfda7eb 3 Written by Stephane Carrez (stcarrez@nerim.fr)
6927f982 4 XGATE and S12X added by James Murray (jsm@jsm-net.demon.co.uk)
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
6927f982
NC
68relax_typeS md_relax_table[] =
69{
fafb6d17
NC
70 {1, 1, 0, 0}, /* First entries aren't used. */
71 {1, 1, 0, 0}, /* For no good reason except. */
72 {1, 1, 0, 0}, /* that the VAX doesn't either. */
60bcf0fa
NC
73 {1, 1, 0, 0},
74
75 /* Relax for bcc <L>.
76 These insns are translated into b!cc +3 jmp L. */
77 {(127), (-128), 0, ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_WORD)},
78 {0, 0, 3, 0},
79 {1, 1, 0, 0},
80 {1, 1, 0, 0},
81
82 /* Relax for bsr <L> and bra <L>.
83 These insns are translated into jsr and jmp. */
84 {(127), (-128), 0, ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD)},
85 {0, 0, 1, 0},
86 {1, 1, 0, 0},
87 {1, 1, 0, 0},
88
89 /* Relax for indexed offset: 5-bits, 9-bits, 16-bits. */
90 {(15), (-16), 0, ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9)},
91 {(255), (-256), 1, ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16)},
88051039 92 {0, 0, 2, 0},
60bcf0fa
NC
93 {1, 1, 0, 0},
94
75538612
SC
95 /* Relax for PC relative offset: 5-bits, 9-bits, 16-bits.
96 For the 9-bit case, there will be a -1 correction to take into
97 account the new byte that's why the range is -255..256. */
98 {(15), (-16), 0, ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS9)},
99 {(256), (-255), 1, ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS16)},
100 {0, 0, 2, 0},
101 {1, 1, 0, 0},
102
60bcf0fa
NC
103 /* Relax for dbeq/ibeq/tbeq r,<L>:
104 These insns are translated into db!cc +3 jmp L. */
105 {(255), (-256), 0, ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_WORD)},
106 {0, 0, 3, 0},
107 {1, 1, 0, 0},
108 {1, 1, 0, 0},
109
110 /* Relax for bcc <L> on 68HC12.
111 These insns are translated into lbcc <L>. */
112 {(127), (-128), 0, ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_WORD)},
113 {0, 0, 2, 0},
114 {1, 1, 0, 0},
115 {1, 1, 0, 0},
116
117};
118
119/* 68HC11 and 68HC12 registers. They are numbered according to the 68HC12. */
6927f982
NC
120typedef enum register_id
121{
60bcf0fa
NC
122 REG_NONE = -1,
123 REG_A = 0,
124 REG_B = 1,
125 REG_CCR = 2,
126 REG_D = 4,
127 REG_X = 5,
128 REG_Y = 6,
129 REG_SP = 7,
6927f982
NC
130 REG_PC = 8,
131 REG_R0 = 0,
132 REG_R1 = 1,
133 REG_R2 = 2,
134 REG_R3 = 3,
135 REG_R4 = 4,
136 REG_R5 = 5,
137 REG_R6 = 6,
138 REG_R7 = 7,
139 REG_SP_XG = 8,
140 REG_PC_XG = 9,
141 REG_CCR_XG = 10
60bcf0fa
NC
142} register_id;
143
6927f982
NC
144typedef struct operand
145{
60bcf0fa
NC
146 expressionS exp;
147 register_id reg1;
148 register_id reg2;
149 int mode;
150} operand;
151
6927f982
NC
152struct m68hc11_opcode_def
153{
60bcf0fa
NC
154 long format;
155 int min_operands;
156 int max_operands;
157 int nb_modes;
158 int used;
159 struct m68hc11_opcode *opcode;
160};
161
162static struct m68hc11_opcode_def *m68hc11_opcode_defs = 0;
163static int m68hc11_nb_opcode_defs = 0;
164
6927f982
NC
165typedef struct alias
166{
60bcf0fa
NC
167 const char *name;
168 const char *alias;
098f2ec3 169} alias;
60bcf0fa 170
6927f982
NC
171static alias alias_opcodes[] =
172{
60bcf0fa
NC
173 {"cpd", "cmpd"},
174 {"cpx", "cmpx"},
175 {"cpy", "cmpy"},
176 {0, 0}
177};
178
6927f982
NC
179struct m9s12xg_opcode_def
180{
181 long format;
182 int min_operands;
183 int max_operands;
184 int nb_modes;
185 int used;
186 struct m9s12xg_opcode *opcode;
187};
188
fafb6d17 189/* Local functions. */
ca43c854
SC
190static register_id reg_name_search (char *);
191static register_id register_name (void);
192static int cmp_opcode (struct m68hc11_opcode *, struct m68hc11_opcode *);
193static char *print_opcode_format (struct m68hc11_opcode *, int);
194static char *skip_whites (char *);
195static int check_range (long, int);
196static void print_opcode_list (void);
197static void get_default_target (void);
198static void print_insn_format (char *);
199static int get_operand (operand *, int, long);
200static void fixup8 (expressionS *, int, int);
201static void fixup16 (expressionS *, int, int);
202static void fixup24 (expressionS *, int, int);
6927f982 203static void fixup8_xg (expressionS *, int, int);
ca43c854
SC
204static unsigned char convert_branch (unsigned char);
205static char *m68hc11_new_insn (int);
206static void build_dbranch_insn (struct m68hc11_opcode *,
207 operand *, int, int);
208static int build_indexed_byte (operand *, int, int);
209static int build_reg_mode (operand *, int);
210
211static struct m68hc11_opcode *find (struct m68hc11_opcode_def *,
212 operand *, int);
213static struct m68hc11_opcode *find_opcode (struct m68hc11_opcode_def *,
214 operand *, int *);
215static void build_jump_insn (struct m68hc11_opcode *, operand *, int, int);
6927f982 216static void build_insn_xg (struct m68hc11_opcode *, operand *, int);
ca43c854
SC
217static void build_insn (struct m68hc11_opcode *, operand *, int);
218static int relaxable_symbol (symbolS *);
60bcf0fa 219
e371935f 220/* Pseudo op to indicate a relax group. */
ca43c854 221static void s_m68hc11_relax (int);
e371935f 222
eb086b59 223/* Pseudo op to control the ELF flags. */
ca43c854 224static void s_m68hc11_mode (int);
eb086b59 225
bdfd67fa
SK
226/* Process directives specified via pseudo ops. */
227static void s_m68hc11_parse_pseudo_instruction (int);
228
eb086b59
SC
229/* Mark the symbols with STO_M68HC12_FAR to indicate the functions
230 are using 'rtc' for returning. It is necessary to use 'call'
231 to invoke them. This is also used by the debugger to correctly
232 find the stack frame. */
ca43c854 233static void s_m68hc11_mark_symbol (int);
eb086b59 234
60bcf0fa
NC
235/* Controls whether relative branches can be turned into long branches.
236 When the relative offset is too large, the insn are changed:
237 bra -> jmp
238 bsr -> jsr
239 bcc -> b!cc +3
240 jmp L
241 dbcc -> db!cc +3
242 jmp L
fafb6d17 243
33eaf5de 244 Setting the flag forbids this. */
1370e33d 245static short flag_fixed_branches = 0;
60bcf0fa
NC
246
247/* Force to use long jumps (absolute) instead of relative branches. */
248static short flag_force_long_jumps = 0;
249
250/* Change the direct addressing mode into an absolute addressing mode
251 when the insn does not support direct addressing.
252 For example, "clr *ZD0" is normally not possible and is changed
253 into "clr ZDO". */
254static short flag_strict_direct_addressing = 1;
255
256/* When an opcode has invalid operand, print out the syntax of the opcode
257 to stderr. */
258static short flag_print_insn_syntax = 0;
259
260/* Dumps the list of instructions with syntax and then exit:
261 1 -> Only dumps the list (sorted by name)
262 2 -> Generate an example (or test) that can be compiled. */
263static short flag_print_opcodes = 0;
264
265/* Opcode hash table. */
629310ab 266static htab_t m68hc11_hash;
60bcf0fa
NC
267
268/* Current cpu (either cpu6811 or cpu6812). This is determined automagically
67c1ffbe 269 by 'get_default_target' by looking at default BFD vector. This is overridden
60bcf0fa
NC
270 with the -m<cpu> option. */
271static int current_architecture = 0;
272
273/* Default cpu determined by 'get_default_target'. */
274static const char *default_cpu;
275
276/* Number of opcodes in the sorted table (filtered by current cpu). */
277static int num_opcodes;
278
279/* The opcodes sorted by name and filtered by current cpu. */
280static struct m68hc11_opcode *m68hc11_sorted_opcodes;
281
eb086b59 282/* ELF flags to set in the output file header. */
2f904664 283static int elf_flags = E_M68HC11_F64;
eb086b59 284
60bcf0fa
NC
285/* These are the machine dependent pseudo-ops. These are included so
286 the assembler can work on the output from the SUN C compiler, which
287 generates these. */
288
289/* This table describes all the machine specific pseudo-ops the assembler
290 has to support. The fields are:
291 pseudo-op name without dot
292 function to call to execute this pseudo-op
293 Integer arg to pass to the function. */
6927f982
NC
294const pseudo_typeS md_pseudo_table[] =
295{
60bcf0fa
NC
296 /* The following pseudo-ops are supported for MRI compatibility. */
297 {"fcb", cons, 1},
298 {"fdb", cons, 2},
6927f982 299 {"fqb", cons, 4},
38a57ae7 300 {"fcc", stringer, 8 + 1},
60bcf0fa 301 {"rmb", s_space, 0},
986c6f4b 302
e629c13f
SC
303 /* Motorola ALIS. */
304 {"xrefb", s_ignore, 0}, /* Same as xref */
305
e371935f
SC
306 /* Gcc driven relaxation. */
307 {"relax", s_m68hc11_relax, 0},
308
eb086b59
SC
309 /* .mode instruction (ala SH). */
310 {"mode", s_m68hc11_mode, 0},
311
312 /* .far instruction. */
313 {"far", s_m68hc11_mark_symbol, STO_M68HC12_FAR},
314
315 /* .interrupt instruction. */
316 {"interrupt", s_m68hc11_mark_symbol, STO_M68HC12_INTERRUPT},
317
bdfd67fa
SK
318 /* .nobankwarning instruction. */
319 {"nobankwarning", s_m68hc11_parse_pseudo_instruction, E_M68HC11_NO_BANK_WARNING},
320
60bcf0fa
NC
321 {0, 0, 0}
322};
60bcf0fa
NC
323\f
324/* Options and initialization. */
325
5a38dc70 326const char *md_shortopts = "Sm:";
60bcf0fa 327
6927f982
NC
328struct option md_longopts[] =
329{
60bcf0fa 330#define OPTION_FORCE_LONG_BRANCH (OPTION_MD_BASE)
1370e33d 331 {"force-long-branches", no_argument, NULL, OPTION_FORCE_LONG_BRANCH},
33eaf5de 332 {"force-long-branchs", no_argument, NULL, OPTION_FORCE_LONG_BRANCH}, /* Misspelled version kept for backwards compatibility. */
60bcf0fa 333
1370e33d
NC
334#define OPTION_SHORT_BRANCHES (OPTION_MD_BASE + 1)
335 {"short-branches", no_argument, NULL, OPTION_SHORT_BRANCHES},
33eaf5de 336 {"short-branchs", no_argument, NULL, OPTION_SHORT_BRANCHES}, /* Misspelled version kept for backwards compatibility. */
60bcf0fa
NC
337
338#define OPTION_STRICT_DIRECT_MODE (OPTION_MD_BASE + 2)
339 {"strict-direct-mode", no_argument, NULL, OPTION_STRICT_DIRECT_MODE},
340
341#define OPTION_PRINT_INSN_SYNTAX (OPTION_MD_BASE + 3)
342 {"print-insn-syntax", no_argument, NULL, OPTION_PRINT_INSN_SYNTAX},
343
344#define OPTION_PRINT_OPCODES (OPTION_MD_BASE + 4)
345 {"print-opcodes", no_argument, NULL, OPTION_PRINT_OPCODES},
346
347#define OPTION_GENERATE_EXAMPLE (OPTION_MD_BASE + 5)
348 {"generate-example", no_argument, NULL, OPTION_GENERATE_EXAMPLE},
349
2f904664
SC
350#define OPTION_MSHORT (OPTION_MD_BASE + 6)
351 {"mshort", no_argument, NULL, OPTION_MSHORT},
352
353#define OPTION_MLONG (OPTION_MD_BASE + 7)
354 {"mlong", no_argument, NULL, OPTION_MLONG},
355
356#define OPTION_MSHORT_DOUBLE (OPTION_MD_BASE + 8)
357 {"mshort-double", no_argument, NULL, OPTION_MSHORT_DOUBLE},
358
359#define OPTION_MLONG_DOUBLE (OPTION_MD_BASE + 9)
360 {"mlong-double", no_argument, NULL, OPTION_MLONG_DOUBLE},
361
6927f982
NC
362#define OPTION_XGATE_RAMOFFSET (OPTION_MD_BASE + 10)
363 {"xgate-ramoffset", no_argument, NULL, OPTION_XGATE_RAMOFFSET},
364
60bcf0fa
NC
365 {NULL, no_argument, NULL, 0}
366};
367size_t md_longopts_size = sizeof (md_longopts);
368
369/* Get the target cpu for the assembler. This is based on the configure
370 options and on the -m68hc11/-m68hc12 option. If no option is specified,
371 we must get the default. */
372const char *
ca43c854 373m68hc11_arch_format (void)
60bcf0fa
NC
374{
375 get_default_target ();
376 if (current_architecture & cpu6811)
377 return "elf32-m68hc11";
378 else
379 return "elf32-m68hc12";
380}
381
382enum bfd_architecture
ca43c854 383m68hc11_arch (void)
60bcf0fa
NC
384{
385 get_default_target ();
386 if (current_architecture & cpu6811)
387 return bfd_arch_m68hc11;
388 else
389 return bfd_arch_m68hc12;
390}
391
392int
ca43c854 393m68hc11_mach (void)
60bcf0fa
NC
394{
395 return 0;
396}
397
986c6f4b
SC
398/* Listing header selected according to cpu. */
399const char *
ca43c854 400m68hc11_listing_header (void)
986c6f4b
SC
401{
402 if (current_architecture & cpu6811)
403 return "M68HC11 GAS ";
6927f982
NC
404 else if (current_architecture & cpuxgate)
405 return "XGATE GAS ";
406 else if (current_architecture & cpu9s12x)
407 return "S12X GAS ";
986c6f4b
SC
408 else
409 return "M68HC12 GAS ";
410}
411
60bcf0fa 412void
ca43c854 413md_show_usage (FILE *stream)
60bcf0fa
NC
414{
415 get_default_target ();
416 fprintf (stream, _("\
d01030e6 417Motorola 68HC11/68HC12/68HCS12 options:\n\
f0abc2a1 418 -m68hc11 | -m68hc12 |\n\
6927f982
NC
419 -m68hcs12 | -mm9s12x |\n\
420 -mm9s12xg specify the processor [default %s]\n\
2f904664
SC
421 -mshort use 16-bit int ABI (default)\n\
422 -mlong use 32-bit int ABI\n\
423 -mshort-double use 32-bit double ABI\n\
424 -mlong-double use 64-bit double ABI (default)\n\
1370e33d
NC
425 --force-long-branches always turn relative branches into absolute ones\n\
426 -S,--short-branches do not turn relative branches into absolute ones\n\
60bcf0fa
NC
427 when the offset is out of range\n\
428 --strict-direct-mode do not turn the direct mode into extended mode\n\
429 when the instruction does not support direct mode\n\
430 --print-insn-syntax print the syntax of instruction in case of error\n\
431 --print-opcodes print the list of instructions with syntax\n\
6927f982 432 --xgate-ramoffset offset ram addresses by 0xc000\n\
60bcf0fa
NC
433 --generate-example generate an example of each instruction\n\
434 (used for testing)\n"), default_cpu);
435
436}
437
438/* Try to identify the default target based on the BFD library. */
439static void
ca43c854 440get_default_target (void)
60bcf0fa
NC
441{
442 const bfd_target *target;
443 bfd abfd;
444
445 if (current_architecture != 0)
446 return;
447
448 default_cpu = "unknown";
449 target = bfd_find_target (0, &abfd);
450 if (target && target->name)
451 {
452 if (strcmp (target->name, "elf32-m68hc12") == 0)
453 {
454 current_architecture = cpu6812;
455 default_cpu = "m68hc12";
456 }
457 else if (strcmp (target->name, "elf32-m68hc11") == 0)
458 {
459 current_architecture = cpu6811;
460 default_cpu = "m68hc11";
461 }
462 else
463 {
464 as_bad (_("Default target `%s' is not supported."), target->name);
465 }
466 }
467}
468
469void
ca43c854 470m68hc11_print_statistics (FILE *file)
60bcf0fa
NC
471{
472 int i;
473 struct m68hc11_opcode_def *opc;
474
629310ab 475 htab_print_statistics (file, "opcode table", m68hc11_hash);
60bcf0fa
NC
476
477 opc = m68hc11_opcode_defs;
478 if (opc == 0 || m68hc11_nb_opcode_defs == 0)
479 return;
480
481 /* Dump the opcode statistics table. */
482 fprintf (file, _("Name # Modes Min ops Max ops Modes mask # Used\n"));
483 for (i = 0; i < m68hc11_nb_opcode_defs; i++, opc++)
484 {
485 fprintf (file, "%-7.7s %5d %7d %7d 0x%08lx %7d\n",
486 opc->opcode->name,
487 opc->nb_modes,
488 opc->min_operands, opc->max_operands, opc->format, opc->used);
489 }
490}
491
492int
17b9d67d 493md_parse_option (int c, const char *arg)
60bcf0fa
NC
494{
495 get_default_target ();
496 switch (c)
497 {
986c6f4b 498 /* -S means keep external to 2 bit offset rather than 16 bit one. */
1370e33d 499 case OPTION_SHORT_BRANCHES:
60bcf0fa 500 case 'S':
1370e33d 501 flag_fixed_branches = 1;
60bcf0fa
NC
502 break;
503
504 case OPTION_FORCE_LONG_BRANCH:
505 flag_force_long_jumps = 1;
506 break;
507
508 case OPTION_PRINT_INSN_SYNTAX:
509 flag_print_insn_syntax = 1;
510 break;
511
512 case OPTION_PRINT_OPCODES:
513 flag_print_opcodes = 1;
514 break;
515
516 case OPTION_STRICT_DIRECT_MODE:
517 flag_strict_direct_addressing = 0;
518 break;
519
520 case OPTION_GENERATE_EXAMPLE:
521 flag_print_opcodes = 2;
522 break;
523
2f904664
SC
524 case OPTION_MSHORT:
525 elf_flags &= ~E_M68HC11_I32;
526 break;
527
528 case OPTION_MLONG:
529 elf_flags |= E_M68HC11_I32;
530 break;
531
532 case OPTION_MSHORT_DOUBLE:
533 elf_flags &= ~E_M68HC11_F64;
534 break;
535
536 case OPTION_MLONG_DOUBLE:
537 elf_flags |= E_M68HC11_F64;
538 break;
539
6927f982
NC
540 case OPTION_XGATE_RAMOFFSET:
541 elf_flags |= E_M68HC11_XGATE_RAMOFFSET;
542 break;
543
60bcf0fa 544 case 'm':
6927f982
NC
545 if ((strcasecmp (arg, "68hc11") == 0)
546 || (strcasecmp (arg, "m68hc11") == 0))
60bcf0fa 547 current_architecture = cpu6811;
6927f982
NC
548 else if ((strcasecmp (arg, "68hc12") == 0)
549 || (strcasecmp (arg, "m68hc12") == 0))
60bcf0fa 550 current_architecture = cpu6812;
6927f982
NC
551 else if ((strcasecmp (arg, "68hcs12") == 0)
552 || (strcasecmp (arg, "m68hcs12") == 0))
d01030e6 553 current_architecture = cpu6812 | cpu6812s;
6927f982
NC
554 else if (strcasecmp (arg, "m9s12x") == 0)
555 current_architecture = cpu6812 | cpu6812s | cpu9s12x;
556 else if ((strcasecmp (arg, "m9s12xg") == 0)
557 || (strcasecmp (arg, "xgate") == 0))
2b0f3761 558 /* xgate for backwards compatibility */
6927f982 559 current_architecture = cpuxgate;
60bcf0fa
NC
560 else
561 as_bad (_("Option `%s' is not recognized."), arg);
562 break;
563
564 default:
565 return 0;
566 }
567
568 return 1;
569}
570\f
571symbolS *
ca43c854 572md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
60bcf0fa
NC
573{
574 return 0;
575}
576
6d4af3c2 577const char *
ca43c854 578md_atof (int type, char *litP, int *sizeP)
60bcf0fa 579{
5b7c81bd 580 return ieee_md_atof (type, litP, sizeP, true);
60bcf0fa
NC
581}
582
583valueT
ca43c854 584md_section_align (asection *seg, valueT addr)
60bcf0fa 585{
fd361982 586 int align = bfd_section_alignment (seg);
8d3842cd 587 return ((addr + (1 << align) - 1) & -(1 << align));
60bcf0fa
NC
588}
589
60bcf0fa 590static int
ca43c854 591cmp_opcode (struct m68hc11_opcode *op1, struct m68hc11_opcode *op2)
60bcf0fa
NC
592{
593 return strcmp (op1->name, op2->name);
594}
595
7bfda7eb
SC
596#define IS_CALL_SYMBOL(MODE) \
597(((MODE) & (M6812_OP_PAGE|M6811_OP_IND16)) \
598 == ((M6812_OP_PAGE|M6811_OP_IND16)))
599
60bcf0fa
NC
600/* Initialize the assembler. Create the opcode hash table
601 (sorted on the names) with the M6811 opcode table
602 (from opcode library). */
603void
ca43c854 604md_begin (void)
60bcf0fa 605{
b9bb4a93 606 const char *prev_name = "";
60bcf0fa
NC
607 struct m68hc11_opcode *opcodes;
608 struct m68hc11_opcode_def *opc = 0;
609 int i, j;
610
611 get_default_target ();
612
629310ab 613 m68hc11_hash = str_htab_create ();
60bcf0fa
NC
614
615 /* Get a writable copy of the opcode table and sort it on the names. */
add39d23 616 opcodes = XNEWVEC (struct m68hc11_opcode, m68hc11_num_opcodes);
60bcf0fa
NC
617 m68hc11_sorted_opcodes = opcodes;
618 num_opcodes = 0;
619 for (i = 0; i < m68hc11_num_opcodes; i++)
620 {
621 if (m68hc11_opcodes[i].arch & current_architecture)
622 {
623 opcodes[num_opcodes] = m68hc11_opcodes[i];
624 if (opcodes[num_opcodes].name[0] == 'b'
625 && opcodes[num_opcodes].format & M6811_OP_JUMP_REL
626 && !(opcodes[num_opcodes].format & M6811_OP_BITMASK))
627 {
628 num_opcodes++;
629 opcodes[num_opcodes] = m68hc11_opcodes[i];
630 }
631 num_opcodes++;
632 for (j = 0; alias_opcodes[j].name != 0; j++)
633 if (strcmp (m68hc11_opcodes[i].name, alias_opcodes[j].name) == 0)
634 {
635 opcodes[num_opcodes] = m68hc11_opcodes[i];
636 opcodes[num_opcodes].name = alias_opcodes[j].alias;
637 num_opcodes++;
638 break;
639 }
640 }
641 }
1910266d 642 qsort (opcodes, num_opcodes, sizeof (struct m68hc11_opcode),
ca43c854 643 (int (*) (const void*, const void*)) cmp_opcode);
60bcf0fa 644
add39d23 645 opc = XNEWVEC (struct m68hc11_opcode_def, num_opcodes);
c61b7b7b 646 m68hc11_opcode_defs = opc;
60bcf0fa
NC
647
648 /* Insert unique names into hash table. The M6811 instruction set
649 has several identical opcode names that have different opcodes based
650 on the operands. This hash table then provides a quick index to
651 the first opcode with a particular name in the opcode table. */
652 for (i = 0; i < num_opcodes; i++, opcodes++)
653 {
654 int expect;
655
656 if (strcmp (prev_name, opcodes->name))
657 {
c61b7b7b 658 prev_name = opcodes->name;
60bcf0fa 659 opc++;
c61b7b7b
AM
660 (opc - 1)->format = 0;
661 (opc - 1)->min_operands = 100;
662 (opc - 1)->max_operands = 0;
663 (opc - 1)->nb_modes = 0;
664 (opc - 1)->opcode = opcodes;
665 (opc - 1)->used = 0;
666 str_hash_insert (m68hc11_hash, opcodes->name, opc - 1, 0);
60bcf0fa 667 }
c61b7b7b
AM
668 (opc - 1)->nb_modes++;
669 (opc - 1)->format |= opcodes->format;
60bcf0fa
NC
670
671 /* See how many operands this opcode needs. */
672 expect = 0;
6927f982
NC
673 if (opcodes->arch == cpuxgate)
674 {
675 if (opcodes->format & (M68XG_OP_IMM3 | M68XG_OP_R | M68XG_OP_REL9
676 | M68XG_OP_REL10 ))
677 expect = 1;
678 else if (opcodes->format & (M68XG_OP_R_R | M68XG_OP_R_IMM4
679 | M68XG_OP_R_IMM8 | M68XG_OP_R_IMM8))
680 expect = 2;
681 else if (opcodes->format & (M68XG_OP_R_R_R | M68XG_OP_R_R_OFFS5
682 | M68XG_OP_RD_RB_RI | M68XG_OP_RD_RB_RIp
683 | M68XG_OP_RD_RB_mRI))
684 expect = 3;
685 }
686 else
687 {
688 if (opcodes->format & M6811_OP_MASK)
689 expect++;
690 if (opcodes->format & M6811_OP_BITMASK)
691 expect++;
692 if (opcodes->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
693 expect++;
694 if (opcodes->format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2))
695 expect++;
696 /* Special case for call instruction. */
697 if ((opcodes->format & M6812_OP_PAGE)
698 && !(opcodes->format & M6811_OP_IND16))
699 expect++;
700 }
60bcf0fa 701
c61b7b7b
AM
702 if (expect < (opc - 1)->min_operands)
703 (opc - 1)->min_operands = expect;
7bfda7eb 704 if (IS_CALL_SYMBOL (opcodes->format))
6927f982 705 expect++;
c61b7b7b
AM
706 if (expect > (opc - 1)->max_operands)
707 (opc - 1)->max_operands = expect;
60bcf0fa 708 }
60bcf0fa
NC
709 m68hc11_nb_opcode_defs = opc - m68hc11_opcode_defs;
710
711 if (flag_print_opcodes)
712 {
713 print_opcode_list ();
714 exit (EXIT_SUCCESS);
715 }
716}
717
718void
ca43c854 719m68hc11_init_after_args (void)
60bcf0fa
NC
720{
721}
60bcf0fa
NC
722\f
723/* Builtin help. */
724
725/* Return a string that represents the operand format for the instruction.
726 When example is true, this generates an example of operand. This is used
727 to give an example and also to generate a test. */
6927f982 728
60bcf0fa 729static char *
ca43c854 730print_opcode_format (struct m68hc11_opcode *opcode, int example)
60bcf0fa
NC
731{
732 static char buf[128];
733 int format = opcode->format;
734 char *p;
735
736 p = buf;
737 buf[0] = 0;
60bcf0fa 738
6927f982 739 if (current_architecture == cpuxgate)
60bcf0fa 740 {
6927f982
NC
741 if (format & M68XG_OP_IMM3)
742 {
743 if (example)
744 sprintf (p, "#%d", rand () & 0x007);
745 else
746 strcpy (p, _("imm3"));
747 p = &p[strlen (p)];
748 }
749 else if (format & M68XG_OP_R)
750 {
751 if (example)
752 sprintf (p, "R%d", rand () & 0x07);
753 else
754 strcpy (p, _("RD"));
755 p = &p[strlen (p)];
756 }
757 else if (format & M68XG_OP_R_R)
758 {
759 if (example)
760 sprintf (p, "R%d,R%d", rand () & 0x07, rand () & 0x07);
761 else
762 strcpy (p, _("RD,RS"));
763 p = &p[strlen (p)];
764 }
765 else if (format & M68XG_OP_R_IMM4)
766 {
767 if (example)
768 sprintf (p, "R%d,#%d", rand () & 0x07, rand () & 0x0f);
769 else
770 strcpy (p, _("RI, #imm4"));
771 p = &p[strlen (p)];
772 }
773 else if (format & M68XG_OP_R_R_R)
774 {
775 if (example)
776 sprintf (p, "R%d,R%d,R%d", rand () & 0x07, rand () & 0x07, rand () & 0x07);
777 else
778 strcpy (p, "RD,RS1,RS2");
779 p = &p[strlen (p)];
780 }
781 else if (format & M68XG_OP_REL9)
782 {
783 if (example)
784 sprintf (p, "%d", rand () & 0x1FF);
785 else
786 strcpy (p, "<rel9>");
787 p = &p[strlen (p)];
788 }
789 else if (format & M68XG_OP_REL10)
790 {
791 if (example)
792 sprintf (p, "%d", rand () & 0x3FF);
793 else
794 strcpy (p, "<rel10>");
795 p = &p[strlen (p)];
796 }
797 else if (format & M68XG_OP_R_R_OFFS5)
798 {
799 if (example)
800 sprintf (p, "R%d, (R%d, #0x%x)", rand () & 0x07, rand () & 0x07, rand () & 0x1f);
801 else
802 strcpy (p, _("RD, (RI,#offs5)"));
803 p = &p[strlen (p)];
804 }
805 else if (format & M68XG_OP_RD_RB_RI)
806 {
807 if (example)
808 sprintf (p, "R%d, (R%d, R%d)", rand () & 0x07, rand () & 0x07, rand () & 0x07);
809 else
810 strcpy (p, "RD, (RB, RI)");
811 p = &p[strlen (p)];
812 }
813 else if (format & M68XG_OP_RD_RB_RIp)
814 {
815 if (example)
816 sprintf (p, "R%d, (R%d, R%d+)", rand () & 0x07, rand () & 0x07, rand () & 0x07);
817 else
818 strcpy (p, "RD, (RB, RI+)");
819 p = &p[strlen (p)];
820 }
821 else if (format & M68XG_OP_RD_RB_mRI)
822 {
823 if (example)
824 sprintf (p, "R%d, (R%d, -R%d)", rand () & 0x07, rand () & 0x07, rand () & 0x07);
825 else
826 strcpy (p, "RD, (RB, -RI)");
827 p = &p[strlen (p)];
828 }
829 else if (format & M68XG_OP_R_IMM8)
830 {
831 if (example)
832 sprintf (p, "R%d, #0x%x", rand () & 0x07, rand () & 0xff);
833 else
834 strcpy (p, "RD, #imm8");
835 p = &p[strlen (p)];
836 }
837 else if (format & M68XG_OP_R_IMM16)
838 {
839 if (example)
840 sprintf (p, "R%d, #0x%x", rand () & 0x07, rand () & 0xffff);
841 else
842 strcpy (p, "RD, #imm16");
843 p = &p[strlen (p)];
844 }
60bcf0fa 845 }
6927f982 846 else
60bcf0fa 847 {
60bcf0fa 848
6927f982
NC
849 if (format & M6811_OP_IMM8)
850 {
851 if (example)
852 sprintf (p, "#%d", rand () & 0x0FF);
853 else
854 strcpy (p, _("#<imm8>"));
855 p = &p[strlen (p)];
856 }
60bcf0fa 857
6927f982
NC
858 if (format & M6811_OP_IMM16)
859 {
860 if (example)
861 sprintf (p, "#%d", rand () & 0x0FFFF);
862 else
863 strcpy (p, _("#<imm16>"));
864 p = &p[strlen (p)];
865 }
60bcf0fa 866
6927f982
NC
867 if (format & M6811_OP_IX)
868 {
869 if (example)
870 sprintf (p, "%d,X", rand () & 0x0FF);
871 else
872 strcpy (p, _("<imm8>,X"));
873 p = &p[strlen (p)];
874 }
7bfda7eb 875
6927f982
NC
876 if (format & M6811_OP_IY)
877 {
878 if (example)
879 sprintf (p, "%d,X", rand () & 0x0FF);
880 else
881 strcpy (p, _("<imm8>,X"));
882 p = &p[strlen (p)];
883 }
60bcf0fa 884
6927f982
NC
885 if (format & M6812_OP_IDX)
886 {
887 if (example)
888 sprintf (p, "%d,X", rand () & 0x0FF);
889 else
890 strcpy (p, "n,r");
891 p = &p[strlen (p)];
892 }
60bcf0fa 893
6927f982
NC
894 if (format & M6812_OP_PAGE)
895 {
896 if (example)
897 sprintf (p, ", %d", rand () & 0x0FF);
898 else
899 strcpy (p, ", <page>");
900 p = &p[strlen (p)];
901 }
60bcf0fa 902
6927f982
NC
903 if (format & M6811_OP_DIRECT)
904 {
905 if (example)
906 sprintf (p, "*Z%d", rand () & 0x0FF);
907 else
908 strcpy (p, _("*<abs8>"));
909 p = &p[strlen (p)];
910 }
60bcf0fa 911
6927f982
NC
912 if (format & M6811_OP_BITMASK)
913 {
914 if (buf[0])
915 *p++ = ' ';
60bcf0fa 916
6927f982
NC
917 if (example)
918 sprintf (p, "#$%02x", rand () & 0x0FF);
919 else
920 strcpy (p, _("#<mask>"));
60bcf0fa 921
6927f982
NC
922 p = &p[strlen (p)];
923 if (format & M6811_OP_JUMP_REL)
924 *p++ = ' ';
925 }
926
927 if (format & M6811_OP_IND16)
60bcf0fa 928 {
6927f982
NC
929 if (example)
930 sprintf (p, _("symbol%d"), rand () & 0x0FF);
60bcf0fa 931 else
6927f982
NC
932 strcpy (p, _("<abs>"));
933
934 p = &p[strlen (p)];
935 }
936
937 if (format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
938 {
939 if (example)
60bcf0fa 940 {
6927f982
NC
941 if (format & M6811_OP_BITMASK)
942 {
943 sprintf (p, ".+%d", rand () & 0x7F);
944 }
945 else
946 {
947 sprintf (p, "L%d", rand () & 0x0FF);
948 }
60bcf0fa 949 }
6927f982
NC
950 else
951 strcpy (p, _("<label>"));
60bcf0fa 952 }
60bcf0fa 953 }
60bcf0fa
NC
954 return buf;
955}
956
957/* Prints the list of instructions with the possible operands. */
958static void
ca43c854 959print_opcode_list (void)
60bcf0fa
NC
960{
961 int i;
b9bb4a93 962 const char *prev_name = "";
60bcf0fa
NC
963 struct m68hc11_opcode *opcodes;
964 int example = flag_print_opcodes == 2;
965
966 if (example)
fafb6d17
NC
967 printf (_("# Example of `%s' instructions\n\t.sect .text\n_start:\n"),
968 default_cpu);
60bcf0fa
NC
969
970 opcodes = m68hc11_sorted_opcodes;
971
972 /* Walk the list sorted on names (by md_begin). We only report
973 one instruction per line, and we collect the different operand
974 formats. */
975 for (i = 0; i < num_opcodes; i++, opcodes++)
976 {
977 char *fmt = print_opcode_format (opcodes, example);
978
979 if (example)
980 {
981 printf ("L%d:\t", i);
982 printf ("%s %s\n", opcodes->name, fmt);
983 }
984 else
985 {
986 if (strcmp (prev_name, opcodes->name))
987 {
988 if (i > 0)
989 printf ("\n");
990
991 printf ("%-5.5s ", opcodes->name);
992 prev_name = (char *) opcodes->name;
993 }
994 if (fmt[0])
995 printf (" [%s]", fmt);
996 }
997 }
998 printf ("\n");
999}
1000
60bcf0fa
NC
1001/* Print the instruction format. This operation is called when some
1002 instruction is not correct. Instruction format is printed as an
1003 error message. */
1004static void
ca43c854 1005print_insn_format (char *name)
60bcf0fa
NC
1006{
1007 struct m68hc11_opcode_def *opc;
1008 struct m68hc11_opcode *opcode;
1009 char buf[128];
1010
629310ab 1011 opc = (struct m68hc11_opcode_def *) str_hash_find (m68hc11_hash, name);
60bcf0fa
NC
1012 if (opc == NULL)
1013 {
1014 as_bad (_("Instruction `%s' is not recognized."), name);
1015 return;
1016 }
1017 opcode = opc->opcode;
1018
1019 as_bad (_("Instruction formats for `%s':"), name);
1020 do
1021 {
1022 char *fmt;
1023
27302d63 1024 fmt = print_opcode_format (opcode, 0);
60bcf0fa
NC
1025 sprintf (buf, "\t%-5.5s %s", opcode->name, fmt);
1026
1027 as_bad ("%s", buf);
1028 opcode++;
1029 }
1030 while (strcmp (opcode->name, name) == 0);
1031}
60bcf0fa
NC
1032\f
1033/* Analysis of 68HC11 and 68HC12 operands. */
1034
1035/* reg_name_search() finds the register number given its name.
1036 Returns the register number or REG_NONE on failure. */
1037static register_id
ca43c854 1038reg_name_search (char *name)
60bcf0fa
NC
1039{
1040 if (strcasecmp (name, "x") == 0 || strcasecmp (name, "ix") == 0)
1041 return REG_X;
1042 if (strcasecmp (name, "y") == 0 || strcasecmp (name, "iy") == 0)
1043 return REG_Y;
1044 if (strcasecmp (name, "a") == 0)
1045 return REG_A;
1046 if (strcasecmp (name, "b") == 0)
1047 return REG_B;
1048 if (strcasecmp (name, "d") == 0)
1049 return REG_D;
1050 if (strcasecmp (name, "sp") == 0)
1051 return REG_SP;
1052 if (strcasecmp (name, "pc") == 0)
1053 return REG_PC;
1054 if (strcasecmp (name, "ccr") == 0)
1055 return REG_CCR;
6927f982
NC
1056/* XGATE */
1057 if (strcasecmp (name, "r0") == 0)
1058 return REG_R0;
1059 if (strcasecmp (name, "r1") == 0)
1060 return REG_R1;
1061 if (strcasecmp (name, "r2") == 0)
1062 return REG_R2;
1063 if (strcasecmp (name, "r3") == 0)
1064 return REG_R3;
1065 if (strcasecmp (name, "r4") == 0)
1066 return REG_R4;
1067 if (strcasecmp (name, "r5") == 0)
1068 return REG_R5;
1069 if (strcasecmp (name, "r6") == 0)
1070 return REG_R6;
1071 if (strcasecmp (name, "r7") == 0)
1072 return REG_R7;
1073 if (strcasecmp (name, "sp") == 0)
1074 return REG_SP_XG;
1075 if (strcasecmp (name, "pc") == 0)
1076 return REG_PC_XG;
1077 if (strcasecmp (name, "ccr") == 0)
1078 return REG_CCR_XG;
60bcf0fa
NC
1079 return REG_NONE;
1080}
1081
1082static char *
ca43c854 1083skip_whites (char *p)
60bcf0fa
NC
1084{
1085 while (*p == ' ' || *p == '\t')
1086 p++;
1087
1088 return p;
1089}
1090
fafb6d17 1091/* Check the string at input_line_pointer
60bcf0fa
NC
1092 to see if it is a valid register name. */
1093static register_id
ca43c854 1094register_name (void)
60bcf0fa
NC
1095{
1096 register_id reg_number;
1097 char c, *p = input_line_pointer;
1098
1099 if (!is_name_beginner (*p++))
1100 return REG_NONE;
1101
1102 while (is_part_of_name (*p++))
1103 continue;
1104
1105 c = *--p;
1106 if (c)
1107 *p++ = 0;
1108
fafb6d17 1109 /* Look to see if it's in the register table. */
60bcf0fa
NC
1110 reg_number = reg_name_search (input_line_pointer);
1111 if (reg_number != REG_NONE)
1112 {
1113 if (c)
1114 *--p = c;
1115
1116 input_line_pointer = p;
1117 return reg_number;
1118 }
1119 if (c)
1120 *--p = c;
1121
1122 return reg_number;
1123}
577300ce
SC
1124#define M6811_OP_CALL_ADDR 0x00800000
1125#define M6811_OP_PAGE_ADDR 0x04000000
60bcf0fa 1126
fafb6d17 1127/* Parse a string of operands and return an array of expressions.
60bcf0fa 1128
7bfda7eb
SC
1129 Operand mode[0] mode[1] exp[0] exp[1]
1130 #n M6811_OP_IMM16 - O_*
1131 *<exp> M6811_OP_DIRECT - O_*
1132 .{+-}<exp> M6811_OP_JUMP_REL - O_*
1133 <exp> M6811_OP_IND16 - O_*
1134 ,r N,r M6812_OP_IDX M6812_OP_REG O_constant O_register
1135 n,-r M6812_PRE_DEC M6812_OP_REG O_constant O_register
1136 n,+r M6812_PRE_INC " "
1137 n,r- M6812_POST_DEC " "
1138 n,r+ M6812_POST_INC " "
1139 A,r B,r D,r M6811_OP_REG M6812_OP_REG O_register O_register
1140 [D,r] M6811_OP_D_IDX M6812_OP_REG O_register O_register
1141 [n,r] M6811_OP_D_IDX_2 M6812_OP_REG O_constant O_register */
60bcf0fa 1142static int
ca43c854 1143get_operand (operand *oper, int which, long opmode)
60bcf0fa
NC
1144{
1145 char *p = input_line_pointer;
1146 int mode;
1147 register_id reg;
1148
1149 oper->exp.X_op = O_absent;
1150 oper->reg1 = REG_NONE;
1151 oper->reg2 = REG_NONE;
1152 mode = M6811_OP_NONE;
1153
1154 p = skip_whites (p);
1155
1156 if (*p == 0 || *p == '\n' || *p == '\r')
1157 {
1158 input_line_pointer = p;
1159 return 0;
1160 }
1161
1162 if (*p == '*' && (opmode & (M6811_OP_DIRECT | M6811_OP_IND16)))
1163 {
1164 mode = M6811_OP_DIRECT;
1165 p++;
1166 }
1167 else if (*p == '#')
1168 {
1169 if (!(opmode & (M6811_OP_IMM8 | M6811_OP_IMM16 | M6811_OP_BITMASK)))
1170 {
1171 as_bad (_("Immediate operand is not allowed for operand %d."),
fafb6d17 1172 which);
60bcf0fa
NC
1173 return -1;
1174 }
1175
1176 mode = M6811_OP_IMM16;
1177 p++;
d34049e8 1178 if (startswith (p, "%hi"))
60bcf0fa
NC
1179 {
1180 p += 3;
1181 mode |= M6811_OP_HIGH_ADDR;
1182 }
d34049e8 1183 else if (startswith (p, "%lo"))
60bcf0fa
NC
1184 {
1185 p += 3;
1186 mode |= M6811_OP_LOW_ADDR;
1187 }
577300ce
SC
1188 /* %page modifier is used to obtain only the page number
1189 of the address of a function. */
d34049e8 1190 else if (startswith (p, "%page"))
577300ce
SC
1191 {
1192 p += 5;
1193 mode |= M6811_OP_PAGE_ADDR;
1194 }
1195
1196 /* %addr modifier is used to obtain the physical address part
1197 of the function (16-bit). For 68HC12 the function will be
1198 mapped in the 16K window at 0x8000 and the value will be
1199 within that window (although the function address may not fit
1200 in 16-bit). See bfd/elf32-m68hc12.c for the translation. */
d34049e8 1201 else if (startswith (p, "%addr"))
577300ce
SC
1202 {
1203 p += 5;
1204 mode |= M6811_OP_CALL_ADDR;
1205 }
60bcf0fa
NC
1206 }
1207 else if (*p == '.' && (p[1] == '+' || p[1] == '-'))
1208 {
1209 p++;
1210 mode = M6811_OP_JUMP_REL;
1211 }
1212 else if (*p == '[')
1213 {
1214 if (current_architecture & cpu6811)
1215 as_bad (_("Indirect indexed addressing is not valid for 68HC11."));
1216
1217 p++;
7bfda7eb 1218 mode = M6812_OP_D_IDX;
60bcf0fa
NC
1219 p = skip_whites (p);
1220 }
1221 else if (*p == ',') /* Special handling of ,x and ,y. */
1222 {
1223 p++;
1224 input_line_pointer = p;
1225
1226 reg = register_name ();
1227 if (reg != REG_NONE)
1228 {
1229 oper->reg1 = reg;
1230 oper->exp.X_op = O_constant;
1231 oper->exp.X_add_number = 0;
1232 oper->mode = M6812_OP_IDX;
1233 return 1;
1234 }
1235 as_bad (_("Spurious `,' or bad indirect register addressing mode."));
1236 return -1;
1237 }
577300ce 1238 /* Handle 68HC12 page specification in 'call foo,%page(bar)'. */
d34049e8 1239 else if ((opmode & M6812_OP_PAGE) && startswith (p, "%page"))
577300ce
SC
1240 {
1241 p += 5;
1242 mode = M6811_OP_PAGE_ADDR | M6812_OP_PAGE | M6811_OP_IND16;
1243 }
60bcf0fa
NC
1244 input_line_pointer = p;
1245
7bfda7eb 1246 if (mode == M6811_OP_NONE || mode == M6812_OP_D_IDX)
60bcf0fa
NC
1247 reg = register_name ();
1248 else
1249 reg = REG_NONE;
1250
1251 if (reg != REG_NONE)
1252 {
1253 p = skip_whites (input_line_pointer);
7bfda7eb 1254 if (*p == ']' && mode == M6812_OP_D_IDX)
60bcf0fa
NC
1255 {
1256 as_bad
1257 (_("Missing second register or offset for indexed-indirect mode."));
1258 return -1;
1259 }
1260
1261 oper->reg1 = reg;
1262 oper->mode = mode | M6812_OP_REG;
1263 if (*p != ',')
1264 {
7bfda7eb 1265 if (mode == M6812_OP_D_IDX)
60bcf0fa
NC
1266 {
1267 as_bad (_("Missing second register for indexed-indirect mode."));
1268 return -1;
1269 }
1270 return 1;
1271 }
1272
1273 p++;
1274 input_line_pointer = p;
1275 reg = register_name ();
1276 if (reg != REG_NONE)
1277 {
1278 p = skip_whites (input_line_pointer);
7bfda7eb 1279 if (mode == M6812_OP_D_IDX)
60bcf0fa
NC
1280 {
1281 if (*p != ']')
1282 {
1283 as_bad (_("Missing `]' to close indexed-indirect mode."));
1284 return -1;
1285 }
1286 p++;
7bfda7eb 1287 oper->mode = M6812_OP_D_IDX;
60bcf0fa
NC
1288 }
1289 input_line_pointer = p;
1290
1291 oper->reg2 = reg;
1292 return 1;
1293 }
1294 return 1;
1295 }
1296
1297 /* In MRI mode, isolate the operand because we can't distinguish
1298 operands from comments. */
1299 if (flag_mri)
1300 {
1301 char c = 0;
1302
1303 p = skip_whites (p);
1304 while (*p && *p != ' ' && *p != '\t')
1305 p++;
1306
1307 if (*p)
1308 {
1309 c = *p;
1310 *p = 0;
1311 }
1312
1313 /* Parse as an expression. */
1314 expression (&oper->exp);
1315
1316 if (c)
1317 {
1318 *p = c;
1319 }
1320 }
1321 else
1322 {
1323 expression (&oper->exp);
1324 }
1325
1326 if (oper->exp.X_op == O_illegal)
1327 {
1328 as_bad (_("Illegal operand."));
1329 return -1;
1330 }
1331 else if (oper->exp.X_op == O_absent)
1332 {
1333 as_bad (_("Missing operand."));
1334 return -1;
1335 }
1336
1337 p = input_line_pointer;
1338
1339 if (mode == M6811_OP_NONE || mode == M6811_OP_DIRECT
7bfda7eb 1340 || mode == M6812_OP_D_IDX)
60bcf0fa
NC
1341 {
1342 p = skip_whites (input_line_pointer);
1343
1344 if (*p == ',')
1345 {
098f2ec3
KH
1346 int possible_mode = M6811_OP_NONE;
1347 char *old_input_line;
7bfda7eb
SC
1348
1349 old_input_line = p;
60bcf0fa
NC
1350 p++;
1351
1352 /* 68HC12 pre increment or decrement. */
1353 if (mode == M6811_OP_NONE)
1354 {
1355 if (*p == '-')
1356 {
ae3e85dd 1357 possible_mode = M6812_PRE_DEC;
60bcf0fa 1358 p++;
60bcf0fa
NC
1359 }
1360 else if (*p == '+')
1361 {
ae3e85dd 1362 possible_mode = M6812_PRE_INC;
60bcf0fa 1363 p++;
60bcf0fa
NC
1364 }
1365 p = skip_whites (p);
1366 }
1367 input_line_pointer = p;
1368 reg = register_name ();
1369
098f2ec3
KH
1370 /* Backtrack if we have a valid constant expression and
1371 it does not correspond to the offset of the 68HC12 indexed
1372 addressing mode (as in N,x). */
1373 if (reg == REG_NONE && mode == M6811_OP_NONE
1374 && possible_mode != M6811_OP_NONE)
1375 {
1376 oper->mode = M6811_OP_IND16 | M6811_OP_JUMP_REL;
1377 input_line_pointer = skip_whites (old_input_line);
1378 return 1;
1379 }
1380
1381 if (possible_mode != M6811_OP_NONE)
1382 mode = possible_mode;
1383
1384 if ((current_architecture & cpu6811)
1385 && possible_mode != M6811_OP_NONE)
1386 as_bad (_("Pre-increment mode is not valid for 68HC11"));
fafb6d17 1387 /* Backtrack. */
60bcf0fa
NC
1388 if (which == 0 && opmode & M6812_OP_IDX_P2
1389 && reg != REG_X && reg != REG_Y
1390 && reg != REG_PC && reg != REG_SP)
1391 {
1392 reg = REG_NONE;
1393 input_line_pointer = p;
1394 }
1395
1396 if (reg == REG_NONE && mode != M6811_OP_DIRECT
1397 && !(mode == M6811_OP_NONE && opmode & M6811_OP_IND16))
1398 {
1399 as_bad (_("Wrong register in register indirect mode."));
1400 return -1;
1401 }
7bfda7eb 1402 if (mode == M6812_OP_D_IDX)
60bcf0fa
NC
1403 {
1404 p = skip_whites (input_line_pointer);
1405 if (*p++ != ']')
1406 {
1407 as_bad (_("Missing `]' to close register indirect operand."));
1408 return -1;
1409 }
1410 input_line_pointer = p;
7bfda7eb
SC
1411 oper->reg1 = reg;
1412 oper->mode = M6812_OP_D_IDX_2;
1413 return 1;
60bcf0fa
NC
1414 }
1415 if (reg != REG_NONE)
1416 {
1417 oper->reg1 = reg;
1418 if (mode == M6811_OP_NONE)
1419 {
1420 p = input_line_pointer;
1421 if (*p == '-')
1422 {
1423 mode = M6812_POST_DEC;
1424 p++;
1425 if (current_architecture & cpu6811)
1426 as_bad
1427 (_("Post-decrement mode is not valid for 68HC11."));
1428 }
1429 else if (*p == '+')
1430 {
1431 mode = M6812_POST_INC;
1432 p++;
1433 if (current_architecture & cpu6811)
1434 as_bad
1435 (_("Post-increment mode is not valid for 68HC11."));
1436 }
1437 else
1438 mode = M6812_OP_IDX;
1439
1440 input_line_pointer = p;
1441 }
1442 else
1443 mode |= M6812_OP_IDX;
1444
1445 oper->mode = mode;
1446 return 1;
1447 }
7bfda7eb 1448 input_line_pointer = old_input_line;
60bcf0fa
NC
1449 }
1450
1451 if (mode == M6812_OP_D_IDX_2)
1452 {
1453 as_bad (_("Invalid indexed indirect mode."));
1454 return -1;
1455 }
1456 }
1457
1458 /* If the mode is not known until now, this is either a label
1459 or an indirect address. */
1460 if (mode == M6811_OP_NONE)
fafb6d17 1461 mode = M6811_OP_IND16 | M6811_OP_JUMP_REL;
60bcf0fa
NC
1462
1463 p = input_line_pointer;
1464 while (*p == ' ' || *p == '\t')
1465 p++;
1466 input_line_pointer = p;
1467 oper->mode = mode;
1468
1469 return 1;
1470}
1471
1472#define M6812_AUTO_INC_DEC (M6812_PRE_INC | M6812_PRE_DEC \
1473 | M6812_POST_INC | M6812_POST_DEC)
1474
1475/* Checks that the number 'num' fits for a given mode. */
1476static int
ca43c854 1477check_range (long num, int mode)
60bcf0fa 1478{
6927f982
NC
1479 if (current_architecture == cpuxgate)
1480 {
1481 switch (mode)
1482 {
1483 case M68XG_OP_IMM3:
1484 return (num >= 0 && num <= 7) ? 1 : 0;
60bcf0fa 1485
6927f982
NC
1486 case M68XG_OP_R_IMM4:
1487 return (num >= 0 && num <= 15) ? 1 : 0;
60bcf0fa 1488
6927f982
NC
1489 case M68XG_OP_R_R_OFFS5:
1490 return (num >= 0 && num <= 31) ? 1 : 0;
60bcf0fa 1491
6927f982
NC
1492 case M68XG_OP_R_IMM8:
1493 return (num >= 0 && num <= 255) ? 1 : 0;
60bcf0fa 1494
6927f982
NC
1495 case M68XG_OP_R_IMM16:
1496 return (num >= 0 && num <= 65535) ? 1 : 0;
60bcf0fa 1497
6927f982
NC
1498 case M68XG_OP_B_MARKER:
1499 return (num >= -512 && num <= 511) ? 1 : 0;
60bcf0fa 1500
6927f982
NC
1501 case M68XG_OP_BRA_MARKER:
1502 return (num >= -1024 && num <= 1023) ? 1 : 0;
60bcf0fa 1503
6927f982
NC
1504 default:
1505 return 0;
1506 }
1507 }
1508 else
1509 {
1510 /* Auto increment and decrement are ok for [-8..8] without 0. */
1511 if (mode & M6812_AUTO_INC_DEC)
1512 return (num != 0 && num <= 8 && num >= -8);
60bcf0fa 1513
6927f982
NC
1514 /* The 68HC12 supports 5, 9 and 16-bit offsets. */
1515 if (mode & (M6812_INDEXED_IND | M6812_INDEXED | M6812_OP_IDX))
1516 mode = M6811_OP_IND16;
60bcf0fa 1517
6927f982
NC
1518 if (mode & M6812_OP_JUMP_REL16)
1519 mode = M6811_OP_IND16;
1520
1521 mode &= ~M6811_OP_BRANCH;
1522 switch (mode)
1523 {
1524 case M6811_OP_IX:
1525 case M6811_OP_IY:
1526 case M6811_OP_DIRECT:
1527 return (num >= 0 && num <= 255) ? 1 : 0;
1528
1529 case M6811_OP_BITMASK:
1530 case M6811_OP_IMM8:
1531 case M6812_OP_PAGE:
1532 return (((num & 0xFFFFFF00) == 0) || ((num & 0xFFFFFF00) == 0xFFFFFF00))
1533 ? 1 : 0;
1534
1535 case M6811_OP_JUMP_REL:
1536 return (num >= -128 && num <= 127) ? 1 : 0;
1537
1538 case M6811_OP_IND16:
1539 case M6811_OP_IND16 | M6812_OP_PAGE:
1540 case M6811_OP_IMM16:
1541 return (((num & 0xFFFF0000) == 0) || ((num & 0xFFFF0000) == 0xFFFF0000))
1542 ? 1 : 0;
1543
1544 case M6812_OP_IBCC_MARKER:
1545 case M6812_OP_TBCC_MARKER:
1546 case M6812_OP_DBCC_MARKER:
1547 return (num >= -256 && num <= 255) ? 1 : 0;
1548
1549 case M6812_OP_TRAP_ID:
1550 return ((num >= 0x30 && num <= 0x39)
1551 || (num >= 0x40 && num <= 0x0ff)) ? 1 : 0;
1552
1553 default:
1554 return 0;
1555 }
60bcf0fa
NC
1556 }
1557}
60bcf0fa
NC
1558\f
1559/* Gas fixup generation. */
1560
1561/* Put a 1 byte expression described by 'oper'. If this expression contains
1562 unresolved symbols, generate an 8-bit fixup. */
1563static void
ca43c854 1564fixup8 (expressionS *oper, int mode, int opmode)
60bcf0fa
NC
1565{
1566 char *f;
1567
1568 f = frag_more (1);
1569
1570 if (oper->X_op == O_constant)
1571 {
1572 if (mode & M6812_OP_TRAP_ID
1573 && !check_range (oper->X_add_number, M6812_OP_TRAP_ID))
1574 {
1575 static char trap_id_warn_once = 0;
1576
b5c37946
SJ
1577 as_bad (_("Trap id `%" PRId64 "' is out of range."),
1578 (int64_t) oper->X_add_number);
60bcf0fa
NC
1579 if (trap_id_warn_once == 0)
1580 {
1581 trap_id_warn_once = 1;
1582 as_bad (_("Trap id must be within [0x30..0x39] or [0x40..0xff]."));
1583 }
1584 }
1585
1586 if (!(mode & M6812_OP_TRAP_ID)
1587 && !check_range (oper->X_add_number, mode))
1588 {
b5c37946
SJ
1589 as_bad (_("Operand out of 8-bit range: `%" PRId64 "'."),
1590 (int64_t) oper->X_add_number);
60bcf0fa
NC
1591 }
1592 number_to_chars_bigendian (f, oper->X_add_number & 0x0FF, 1);
1593 }
1594 else if (oper->X_op != O_register)
1595 {
1596 if (mode & M6812_OP_TRAP_ID)
1597 as_bad (_("The trap id must be a constant."));
1598
1599 if (mode == M6811_OP_JUMP_REL)
1600 {
9798e45d 1601 fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
5b7c81bd 1602 oper, true, BFD_RELOC_8_PCREL);
60bcf0fa
NC
1603 }
1604 else
1605 {
577300ce 1606 fixS *fixp;
e1838240 1607 bfd_reloc_code_real_type reloc;
577300ce
SC
1608
1609 /* Now create an 8-bit fixup. If there was some %hi, %lo
1610 or %page modifier, generate the reloc accordingly. */
1611 if (opmode & M6811_OP_HIGH_ADDR)
1612 reloc = BFD_RELOC_M68HC11_HI8;
1613 else if (opmode & M6811_OP_LOW_ADDR)
1614 reloc = BFD_RELOC_M68HC11_LO8;
1615 else if (opmode & M6811_OP_PAGE_ADDR)
1616 reloc = BFD_RELOC_M68HC11_PAGE;
1617 else
1618 reloc = BFD_RELOC_8;
1619
1620 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
5b7c81bd 1621 oper, false, reloc);
577300ce
SC
1622 if (reloc != BFD_RELOC_8)
1623 fixp->fx_no_overflow = 1;
60bcf0fa
NC
1624 }
1625 number_to_chars_bigendian (f, 0, 1);
1626 }
1627 else
1628 {
1629 as_fatal (_("Operand `%x' not recognized in fixup8."), oper->X_op);
1630 }
1631}
1632
986c6f4b 1633/* Put a 2 byte expression described by 'oper'. If this expression contains
60bcf0fa
NC
1634 unresolved symbols, generate a 16-bit fixup. */
1635static void
ca43c854 1636fixup16 (expressionS *oper, int mode, int opmode ATTRIBUTE_UNUSED)
60bcf0fa
NC
1637{
1638 char *f;
1639
1640 f = frag_more (2);
1641
1642 if (oper->X_op == O_constant)
1643 {
1644 if (!check_range (oper->X_add_number, mode))
1645 {
b5c37946
SJ
1646 as_bad (_("Operand out of 16-bit range: `%" PRId64 "'."),
1647 (int64_t) oper->X_add_number);
60bcf0fa
NC
1648 }
1649 number_to_chars_bigendian (f, oper->X_add_number & 0x0FFFF, 2);
1650 }
1651 else if (oper->X_op != O_register)
1652 {
1653 fixS *fixp;
e1838240 1654 bfd_reloc_code_real_type reloc;
577300ce
SC
1655
1656 if ((opmode & M6811_OP_CALL_ADDR) && (mode & M6811_OP_IMM16))
1657 reloc = BFD_RELOC_M68HC11_LO16;
1658 else if (mode & M6812_OP_JUMP_REL16)
1659 reloc = BFD_RELOC_16_PCREL;
1660 else if (mode & M6812_OP_PAGE)
1661 reloc = BFD_RELOC_M68HC11_LO16;
1662 else
1663 reloc = BFD_RELOC_16;
60bcf0fa
NC
1664
1665 /* Now create a 16-bit fixup. */
1666 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 2,
1667 oper,
577300ce
SC
1668 reloc == BFD_RELOC_16_PCREL,
1669 reloc);
60bcf0fa 1670 number_to_chars_bigendian (f, 0, 2);
9798e45d 1671
577300ce
SC
1672 if (reloc == BFD_RELOC_M68HC11_LO16)
1673 fixp->fx_no_overflow = 1;
60bcf0fa
NC
1674 }
1675 else
1676 {
1677 as_fatal (_("Operand `%x' not recognized in fixup16."), oper->X_op);
1678 }
1679}
7bfda7eb
SC
1680
1681/* Put a 3 byte expression described by 'oper'. If this expression contains
1682 unresolved symbols, generate a 24-bit fixup. */
1683static void
ca43c854 1684fixup24 (expressionS *oper, int mode, int opmode ATTRIBUTE_UNUSED)
7bfda7eb
SC
1685{
1686 char *f;
1687
1688 f = frag_more (3);
1689
1690 if (oper->X_op == O_constant)
1691 {
1692 if (!check_range (oper->X_add_number, mode))
1693 {
b5c37946
SJ
1694 as_bad (_("Operand out of 16-bit range: `%" PRId64 "'."),
1695 (int64_t) oper->X_add_number);
7bfda7eb
SC
1696 }
1697 number_to_chars_bigendian (f, oper->X_add_number & 0x0FFFFFF, 3);
1698 }
1699 else if (oper->X_op != O_register)
1700 {
7bfda7eb 1701 /* Now create a 24-bit fixup. */
87975d2a 1702 fix_new_exp (frag_now, f - frag_now->fr_literal, 3,
5b7c81bd 1703 oper, false, BFD_RELOC_M68HC11_24);
7bfda7eb
SC
1704 number_to_chars_bigendian (f, 0, 3);
1705 }
1706 else
1707 {
1708 as_fatal (_("Operand `%x' not recognized in fixup16."), oper->X_op);
1709 }
1710}
6927f982
NC
1711
1712/* XGATE Put a 1 byte expression described by 'oper'. If this expression
33eaf5de 1713 contains unresolved symbols, generate an 8-bit fixup. */
6927f982
NC
1714static void
1715fixup8_xg (expressionS *oper, int mode, int opmode)
1716{
1717 char *f;
1718
1719 f = frag_more (1);
1720
1721 if (oper->X_op == O_constant)
1722 {
1723 fixS *fixp;
e1838240 1724 bfd_reloc_code_real_type reloc;
6927f982
NC
1725
1726 if ((opmode & M6811_OP_HIGH_ADDR) || (opmode & M6811_OP_LOW_ADDR))
1727 {
1728 if (opmode & M6811_OP_HIGH_ADDR)
1729 reloc = BFD_RELOC_M68HC11_HI8;
1730 else
1731 reloc = BFD_RELOC_M68HC11_LO8;
1732
1733 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
5b7c81bd 1734 oper, false, reloc);
6927f982
NC
1735 fixp->fx_no_overflow = 1;
1736 number_to_chars_bigendian (f, 0, 1);
1737 }
1738 else
1739 {
1740 if (!(check_range (oper->X_add_number, mode)))
b5c37946
SJ
1741 as_bad (_("Operand out of 8-bit range: `%" PRId64 "'."),
1742 (int64_t) oper->X_add_number);
6927f982
NC
1743 number_to_chars_bigendian (f, oper->X_add_number & 0x0FF, 1);
1744 }
1745 }
1746 else if (oper->X_op != O_register)
1747 {
1748 if (mode == M68XG_OP_REL9)
1749 {
6927f982
NC
1750 /* Future improvement:
1751 This fixup/reloc isn't adding on constants to symbols. */
9798e45d 1752 fix_new_exp (frag_now, f - frag_now->fr_literal -1, 2,
5b7c81bd 1753 oper, true, BFD_RELOC_M68HC12_9_PCREL);
6927f982
NC
1754 }
1755 else if (mode == M68XG_OP_REL10)
1756 {
6927f982
NC
1757 /* Future improvement:
1758 This fixup/reloc isn't adding on constants to symbols. */
9798e45d 1759 fix_new_exp (frag_now, f - frag_now->fr_literal -1, 2,
5b7c81bd 1760 oper, true, BFD_RELOC_M68HC12_10_PCREL);
6927f982
NC
1761 }
1762 else
1763 {
1764 fixS *fixp;
e1838240 1765 bfd_reloc_code_real_type reloc;
6927f982
NC
1766
1767 /* Now create an 8-bit fixup. If there was some %hi, %lo
1768 modifier, generate the reloc accordingly. */
1769 if (opmode & M6811_OP_HIGH_ADDR)
1770 reloc = BFD_RELOC_M68HC11_HI8;
1771 else if (opmode & M6811_OP_LOW_ADDR)
1772 reloc = BFD_RELOC_M68HC11_LO8;
1773 else
1774 reloc = BFD_RELOC_8;
1775
1776 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
5b7c81bd 1777 oper, false, reloc);
6927f982
NC
1778 if (reloc != BFD_RELOC_8)
1779 fixp->fx_no_overflow = 1;
1780 }
1781 number_to_chars_bigendian (f, 0, 1);
1782 }
1783 else
1784 as_fatal (_("Operand `%x' not recognized in fixup8."), oper->X_op);
1785}
60bcf0fa
NC
1786\f
1787/* 68HC11 and 68HC12 code generation. */
1788
1789/* Translate the short branch/bsr instruction into a long branch. */
6927f982 1790
60bcf0fa 1791static unsigned char
ca43c854 1792convert_branch (unsigned char code)
60bcf0fa
NC
1793{
1794 if (IS_OPCODE (code, M6812_BSR))
1795 return M6812_JSR;
1796 else if (IS_OPCODE (code, M6811_BSR))
1797 return M6811_JSR;
1798 else if (IS_OPCODE (code, M6811_BRA))
1799 return (current_architecture & cpu6812) ? M6812_JMP : M6811_JMP;
1800 else
1801 as_fatal (_("Unexpected branch conversion with `%x'"), code);
1802
1803 /* Keep gcc happy. */
1804 return M6811_JSR;
1805}
1806
1807/* Start a new insn that contains at least 'size' bytes. Record the
1808 line information of that insn in the dwarf2 debug sections. */
fafb6d17 1809static char *
ca43c854 1810m68hc11_new_insn (int size)
60bcf0fa 1811{
fafb6d17 1812 char *f;
60bcf0fa
NC
1813
1814 f = frag_more (size);
1815
4dc7ead9 1816 dwarf2_emit_insn (size);
fafb6d17 1817
60bcf0fa
NC
1818 return f;
1819}
1820
1821/* Builds a jump instruction (bra, bcc, bsr). */
1822static void
ca43c854
SC
1823build_jump_insn (struct m68hc11_opcode *opcode, operand operands[],
1824 int nb_operands, int jmp_mode)
60bcf0fa
NC
1825{
1826 unsigned char code;
60bcf0fa
NC
1827 char *f;
1828 unsigned long n;
1829
67c1ffbe 1830 /* The relative branch conversion is not supported for
60bcf0fa 1831 brclr and brset. */
9c2799c2
NC
1832 gas_assert ((opcode->format & M6811_OP_BITMASK) == 0);
1833 gas_assert (nb_operands == 1);
1834 gas_assert (operands[0].reg1 == REG_NONE && operands[0].reg2 == REG_NONE);
60bcf0fa
NC
1835
1836 code = opcode->opcode;
60bcf0fa
NC
1837
1838 n = operands[0].exp.X_add_number;
1839
1840 /* Turn into a long branch:
1841 - when force long branch option (and not for jbcc pseudos),
1842 - when jbcc and the constant is out of -128..127 range,
1843 - when branch optimization is allowed and branch out of range. */
1844 if ((jmp_mode == 0 && flag_force_long_jumps)
1845 || (operands[0].exp.X_op == O_constant
1846 && (!check_range (n, opcode->format) &&
1370e33d 1847 (jmp_mode == 1 || flag_fixed_branches == 0))))
60bcf0fa 1848 {
fd99afa7 1849 fix_new (frag_now, frag_now_fix (), 0,
e371935f
SC
1850 &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
1851
60bcf0fa
NC
1852 if (code == M6811_BSR || code == M6811_BRA || code == M6812_BSR)
1853 {
1854 code = convert_branch (code);
1855
1856 f = m68hc11_new_insn (1);
1857 number_to_chars_bigendian (f, code, 1);
1858 }
1859 else if (current_architecture & cpu6812)
1860 {
1861 /* 68HC12: translate the bcc into a lbcc. */
1862 f = m68hc11_new_insn (2);
1863 number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1);
1864 number_to_chars_bigendian (f + 1, code, 1);
1865 fixup16 (&operands[0].exp, M6812_OP_JUMP_REL16,
1866 M6812_OP_JUMP_REL16);
1867 return;
1868 }
1869 else
1870 {
1871 /* 68HC11: translate the bcc into b!cc +3; jmp <L>. */
1872 f = m68hc11_new_insn (3);
1873 code ^= 1;
1874 number_to_chars_bigendian (f, code, 1);
1875 number_to_chars_bigendian (f + 1, 3, 1);
1876 number_to_chars_bigendian (f + 2, M6811_JMP, 1);
1877 }
1878 fixup16 (&operands[0].exp, M6811_OP_IND16, M6811_OP_IND16);
1879 return;
1880 }
1881
1882 /* Branch with a constant that must fit in 8-bits. */
1883 if (operands[0].exp.X_op == O_constant)
1884 {
1885 if (!check_range (n, opcode->format))
1886 {
1887 as_bad (_("Operand out of range for a relative branch: `%ld'"),
1888 n);
1889 }
1890 else if (opcode->format & M6812_OP_JUMP_REL16)
1891 {
1892 f = m68hc11_new_insn (4);
1893 number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1);
1894 number_to_chars_bigendian (f + 1, code, 1);
1895 number_to_chars_bigendian (f + 2, n & 0x0ffff, 2);
1896 }
1897 else
1898 {
1899 f = m68hc11_new_insn (2);
1900 number_to_chars_bigendian (f, code, 1);
1901 number_to_chars_bigendian (f + 1, n & 0x0FF, 1);
1902 }
1903 }
1904 else if (opcode->format & M6812_OP_JUMP_REL16)
1905 {
fd99afa7 1906 fix_new (frag_now, frag_now_fix (), 0,
e371935f
SC
1907 &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
1908
60bcf0fa
NC
1909 f = m68hc11_new_insn (2);
1910 number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1);
1911 number_to_chars_bigendian (f + 1, code, 1);
1912 fixup16 (&operands[0].exp, M6812_OP_JUMP_REL16, M6812_OP_JUMP_REL16);
1913 }
1914 else
1915 {
91d6fa6a 1916 char *op;
60bcf0fa 1917
fd99afa7 1918 fix_new (frag_now, frag_now_fix (), 0,
e371935f
SC
1919 &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
1920
60bcf0fa 1921 /* Branch offset must fit in 8-bits, don't do some relax. */
1370e33d 1922 if (jmp_mode == 0 && flag_fixed_branches)
60bcf0fa 1923 {
91d6fa6a
NC
1924 op = m68hc11_new_insn (1);
1925 number_to_chars_bigendian (op, code, 1);
60bcf0fa
NC
1926 fixup8 (&operands[0].exp, M6811_OP_JUMP_REL, M6811_OP_JUMP_REL);
1927 }
1928
1929 /* bra/bsr made be changed into jmp/jsr. */
1930 else if (code == M6811_BSR || code == M6811_BRA || code == M6812_BSR)
1931 {
4fe7ef96 1932 /* Allocate worst case storage. */
91d6fa6a
NC
1933 op = m68hc11_new_insn (3);
1934 number_to_chars_bigendian (op, code, 1);
1935 number_to_chars_bigendian (op + 1, 0, 1);
4fe7ef96
SC
1936 frag_variant (rs_machine_dependent, 1, 1,
1937 ENCODE_RELAX (STATE_PC_RELATIVE, STATE_UNDF),
1938 operands[0].exp.X_add_symbol, (offsetT) n,
91d6fa6a 1939 op);
60bcf0fa
NC
1940 }
1941 else if (current_architecture & cpu6812)
1942 {
91d6fa6a
NC
1943 op = m68hc11_new_insn (2);
1944 number_to_chars_bigendian (op, code, 1);
1945 number_to_chars_bigendian (op + 1, 0, 1);
60bcf0fa
NC
1946 frag_var (rs_machine_dependent, 2, 2,
1947 ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_UNDF),
91d6fa6a 1948 operands[0].exp.X_add_symbol, (offsetT) n, op);
60bcf0fa
NC
1949 }
1950 else
1951 {
91d6fa6a
NC
1952 op = m68hc11_new_insn (2);
1953 number_to_chars_bigendian (op, code, 1);
1954 number_to_chars_bigendian (op + 1, 0, 1);
60bcf0fa
NC
1955 frag_var (rs_machine_dependent, 3, 3,
1956 ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_UNDF),
91d6fa6a 1957 operands[0].exp.X_add_symbol, (offsetT) n, op);
60bcf0fa
NC
1958 }
1959 }
1960}
1961
1962/* Builds a dbne/dbeq/tbne/tbeq instruction. */
1963static void
ca43c854
SC
1964build_dbranch_insn (struct m68hc11_opcode *opcode, operand operands[],
1965 int nb_operands, int jmp_mode)
60bcf0fa
NC
1966{
1967 unsigned char code;
60bcf0fa
NC
1968 char *f;
1969 unsigned long n;
1970
67c1ffbe 1971 /* The relative branch conversion is not supported for
60bcf0fa 1972 brclr and brset. */
9c2799c2
NC
1973 gas_assert ((opcode->format & M6811_OP_BITMASK) == 0);
1974 gas_assert (nb_operands == 2);
1975 gas_assert (operands[0].reg1 != REG_NONE);
60bcf0fa
NC
1976
1977 code = opcode->opcode & 0x0FF;
60bcf0fa
NC
1978
1979 f = m68hc11_new_insn (1);
1980 number_to_chars_bigendian (f, code, 1);
1981
1982 n = operands[1].exp.X_add_number;
1983 code = operands[0].reg1;
1984
1985 if (operands[0].reg1 == REG_NONE || operands[0].reg1 == REG_CCR
1986 || operands[0].reg1 == REG_PC)
1987 as_bad (_("Invalid register for dbcc/tbcc instruction."));
1988
1989 if (opcode->format & M6812_OP_IBCC_MARKER)
1990 code |= 0x80;
1991 else if (opcode->format & M6812_OP_TBCC_MARKER)
1992 code |= 0x40;
1993
1994 if (!(opcode->format & M6812_OP_EQ_MARKER))
1995 code |= 0x20;
1996
1997 /* Turn into a long branch:
1998 - when force long branch option (and not for jbcc pseudos),
1999 - when jdbcc and the constant is out of -256..255 range,
2000 - when branch optimization is allowed and branch out of range. */
2001 if ((jmp_mode == 0 && flag_force_long_jumps)
2002 || (operands[1].exp.X_op == O_constant
2003 && (!check_range (n, M6812_OP_IBCC_MARKER) &&
1370e33d 2004 (jmp_mode == 1 || flag_fixed_branches == 0))))
60bcf0fa
NC
2005 {
2006 f = frag_more (2);
2007 code ^= 0x20;
2008 number_to_chars_bigendian (f, code, 1);
2009 number_to_chars_bigendian (f + 1, M6812_JMP, 1);
2010 fixup16 (&operands[0].exp, M6811_OP_IND16, M6811_OP_IND16);
2011 return;
2012 }
2013
2014 /* Branch with a constant that must fit in 9-bits. */
2015 if (operands[1].exp.X_op == O_constant)
2016 {
2017 if (!check_range (n, M6812_OP_IBCC_MARKER))
2018 {
2019 as_bad (_("Operand out of range for a relative branch: `%ld'"),
2020 n);
2021 }
2022 else
2023 {
2024 if ((long) n < 0)
2025 code |= 0x10;
2026
2027 f = frag_more (2);
2028 number_to_chars_bigendian (f, code, 1);
2029 number_to_chars_bigendian (f + 1, n & 0x0FF, 1);
2030 }
2031 }
2032 else
2033 {
2034 /* Branch offset must fit in 8-bits, don't do some relax. */
1370e33d 2035 if (jmp_mode == 0 && flag_fixed_branches)
60bcf0fa
NC
2036 {
2037 fixup8 (&operands[0].exp, M6811_OP_JUMP_REL, M6811_OP_JUMP_REL);
2038 }
2039
2040 else
2041 {
2042 f = frag_more (2);
2043 number_to_chars_bigendian (f, code, 1);
2044 number_to_chars_bigendian (f + 1, 0, 1);
2045 frag_var (rs_machine_dependent, 3, 3,
2046 ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_UNDF),
2047 operands[1].exp.X_add_symbol, (offsetT) n, f);
2048 }
2049 }
2050}
2051
2052#define OP_EXTENDED (M6811_OP_PAGE2 | M6811_OP_PAGE3 | M6811_OP_PAGE4)
2053
2054/* Assemble the post index byte for 68HC12 extended addressing modes. */
6927f982 2055
60bcf0fa 2056static int
ca43c854 2057build_indexed_byte (operand *op, int format ATTRIBUTE_UNUSED, int move_insn)
60bcf0fa
NC
2058{
2059 unsigned char byte = 0;
2060 char *f;
2061 int mode;
2062 long val;
2063
2064 val = op->exp.X_add_number;
2065 mode = op->mode;
2066 if (mode & M6812_AUTO_INC_DEC)
2067 {
2068 byte = 0x20;
2069 if (mode & (M6812_POST_INC | M6812_POST_DEC))
2070 byte |= 0x10;
2071
2072 if (op->exp.X_op == O_constant)
2073 {
2074 if (!check_range (val, mode))
6927f982
NC
2075 as_bad (_("Increment/decrement value is out of range: `%ld'."),
2076 val);
2077
60bcf0fa
NC
2078 if (mode & (M6812_POST_INC | M6812_PRE_INC))
2079 byte |= (val - 1) & 0x07;
2080 else
2081 byte |= (8 - ((val) & 7)) | 0x8;
2082 }
6927f982 2083
60bcf0fa
NC
2084 switch (op->reg1)
2085 {
2086 case REG_NONE:
2087 as_fatal (_("Expecting a register."));
2088
2089 case REG_X:
2090 byte |= 0;
2091 break;
2092
2093 case REG_Y:
2094 byte |= 0x40;
2095 break;
2096
2097 case REG_SP:
2098 byte |= 0x80;
2099 break;
2100
2101 default:
2102 as_bad (_("Invalid register for post/pre increment."));
2103 break;
2104 }
2105
2106 f = frag_more (1);
2107 number_to_chars_bigendian (f, byte, 1);
2108 return 1;
2109 }
2110
7bfda7eb 2111 if (mode & (M6812_OP_IDX | M6812_OP_D_IDX_2))
60bcf0fa
NC
2112 {
2113 switch (op->reg1)
2114 {
2115 case REG_X:
2116 byte = 0;
2117 break;
2118
2119 case REG_Y:
2120 byte = 1;
2121 break;
2122
2123 case REG_SP:
2124 byte = 2;
2125 break;
2126
2127 case REG_PC:
2128 byte = 3;
2129 break;
2130
2131 default:
2132 as_bad (_("Invalid register."));
2133 break;
2134 }
6927f982 2135
60bcf0fa
NC
2136 if (op->exp.X_op == O_constant)
2137 {
2138 if (!check_range (val, M6812_OP_IDX))
6927f982 2139 as_bad (_("Offset out of 16-bit range: %ld."), val);
60bcf0fa 2140
3739860c
L
2141 if (move_insn && !(val >= -16 && val <= 15)
2142 && ((!(mode & M6812_OP_IDX) && !(mode & M6812_OP_D_IDX_2))
6927f982 2143 || !(current_architecture & cpu9s12x)))
60bcf0fa 2144 {
ae3e85dd 2145 as_bad (_("Offset out of 5-bit range for movw/movb insn: %ld."),
098f2ec3 2146 val);
60bcf0fa
NC
2147 return -1;
2148 }
2149
7bfda7eb 2150 if (val >= -16 && val <= 15 && !(mode & M6812_OP_D_IDX_2))
60bcf0fa
NC
2151 {
2152 byte = byte << 6;
2153 byte |= val & 0x1f;
2154 f = frag_more (1);
2155 number_to_chars_bigendian (f, byte, 1);
2156 return 1;
2157 }
7bfda7eb 2158 else if (val >= -256 && val <= 255 && !(mode & M6812_OP_D_IDX_2))
60bcf0fa
NC
2159 {
2160 byte = byte << 3;
2161 byte |= 0xe0;
2162 if (val < 0)
2163 byte |= 0x1;
2164 f = frag_more (2);
2165 number_to_chars_bigendian (f, byte, 1);
2166 number_to_chars_bigendian (f + 1, val & 0x0FF, 1);
2167 return 2;
2168 }
2169 else
2170 {
2171 byte = byte << 3;
7bfda7eb 2172 if (mode & M6812_OP_D_IDX_2)
60bcf0fa
NC
2173 byte |= 0xe3;
2174 else
2175 byte |= 0xe2;
2176
2177 f = frag_more (3);
2178 number_to_chars_bigendian (f, byte, 1);
2179 number_to_chars_bigendian (f + 1, val & 0x0FFFF, 2);
2180 return 3;
2181 }
2182 }
6927f982 2183
7bfda7eb
SC
2184 if (mode & M6812_OP_D_IDX_2)
2185 {
2186 byte = (byte << 3) | 0xe3;
2187 f = frag_more (1);
2188 number_to_chars_bigendian (f, byte, 1);
2189
2190 fixup16 (&op->exp, 0, 0);
2191 }
2192 else if (op->reg1 != REG_PC)
098f2ec3 2193 {
c9e03e8b
SC
2194 symbolS *sym;
2195 offsetT off;
2196
098f2ec3
KH
2197 f = frag_more (1);
2198 number_to_chars_bigendian (f, byte, 1);
c9e03e8b
SC
2199 sym = op->exp.X_add_symbol;
2200 off = op->exp.X_add_number;
2201 if (op->exp.X_op != O_symbol)
2202 {
2203 sym = make_expr_symbol (&op->exp);
2204 off = 0;
2205 }
6927f982 2206
28d39d1a
NC
2207 /* movb/movw cannot be relaxed. */
2208 if (move_insn)
2209 {
6927f982
NC
2210 if ((mode & M6812_OP_IDX) && (current_architecture & cpu9s12x))
2211 {
2212 /* Must treat as a 16bit relocate as size of final result is unknown. */
2213
2214 byte <<= 3;
6832c67c 2215 byte |= 0xe2;
6927f982 2216 number_to_chars_bigendian (f, byte, 1);
fcdc4d0c 2217 f = frag_more (2);
6927f982
NC
2218 fix_new (frag_now, f - frag_now->fr_literal, 2,
2219 sym, off, 0, BFD_RELOC_M68HC12_16B);
6927f982
NC
2220 return 1;
2221 }
2222 else
2223 {
2224 /* Non-S12X will fail at relocate stage if offset out of range. */
2225 byte <<= 6;
2226 number_to_chars_bigendian (f, byte, 1);
2227 fix_new (frag_now, f - frag_now->fr_literal, 1,
2228 sym, off, 0, BFD_RELOC_M68HC12_5B);
2229 return 1;
2230 }
28d39d1a
NC
2231 }
2232 else
2233 {
2234 number_to_chars_bigendian (f, byte, 1);
2235 frag_var (rs_machine_dependent, 2, 2,
2236 ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_UNDF),
2237 sym, off, f);
2238 }
098f2ec3 2239 }
88051039 2240 else
098f2ec3
KH
2241 {
2242 f = frag_more (1);
6927f982 2243
28d39d1a
NC
2244 /* movb/movw cannot be relaxed. */
2245 if (move_insn)
2246 {
2247 byte <<= 6;
2248 number_to_chars_bigendian (f, byte, 1);
2249 fix_new (frag_now, f - frag_now->fr_literal, 1,
2250 op->exp.X_add_symbol, op->exp.X_add_number, 0, BFD_RELOC_M68HC12_5B);
2251 return 1;
2252 }
2253 else
2254 {
2255 number_to_chars_bigendian (f, byte, 1);
2256 frag_var (rs_machine_dependent, 2, 2,
2257 ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_UNDF),
2258 op->exp.X_add_symbol,
2259 op->exp.X_add_number, f);
2260 }
098f2ec3 2261 }
60bcf0fa
NC
2262 return 3;
2263 }
2264
7bfda7eb 2265 if (mode & (M6812_OP_REG | M6812_OP_D_IDX))
60bcf0fa 2266 {
7bfda7eb 2267 if (mode & M6812_OP_D_IDX)
60bcf0fa
NC
2268 {
2269 if (op->reg1 != REG_D)
2270 as_bad (_("Expecting register D for indexed indirect mode."));
6927f982 2271 if ((move_insn) && (!(current_architecture & cpu9s12x)))
60bcf0fa
NC
2272 as_bad (_("Indexed indirect mode is not allowed for movb/movw."));
2273
2274 byte = 0xE7;
2275 }
2276 else
2277 {
2278 switch (op->reg1)
2279 {
2280 case REG_A:
2281 byte = 0xE4;
2282 break;
2283
2284 case REG_B:
2285 byte = 0xE5;
2286 break;
2287
2288 default:
2289 as_bad (_("Invalid accumulator register."));
1a0670f3 2290 /* Fall through. */
60bcf0fa
NC
2291
2292 case REG_D:
2293 byte = 0xE6;
2294 break;
2295 }
2296 }
2297 switch (op->reg2)
2298 {
2299 case REG_X:
2300 break;
2301
2302 case REG_Y:
2303 byte |= (1 << 3);
2304 break;
2305
2306 case REG_SP:
2307 byte |= (2 << 3);
2308 break;
2309
2310 case REG_PC:
2311 byte |= (3 << 3);
2312 break;
2313
2314 default:
2315 as_bad (_("Invalid indexed register."));
2316 break;
2317 }
2318 f = frag_more (1);
2319 number_to_chars_bigendian (f, byte, 1);
2320 return 1;
2321 }
2322
6927f982
NC
2323 fprintf (stderr, "mode = 0x%x\nop->reg1 = 0x%x\nop->reg2 = 0x%x\n",
2324 mode, op->reg1, op->reg2);
60bcf0fa
NC
2325 as_fatal (_("Addressing mode not implemented yet."));
2326 return 0;
2327}
2328
2329/* Assemble the 68HC12 register mode byte. */
2330static int
ca43c854 2331build_reg_mode (operand *op, int format)
60bcf0fa
NC
2332{
2333 unsigned char byte;
2334 char *f;
2335
6927f982
NC
2336 if ((format & M6812_OP_SEX_MARKER)
2337 && (op->reg1 != REG_A) && (op->reg1 != REG_B) && (op->reg1 != REG_CCR)
2338 && (!(current_architecture & cpu9s12x)))
60bcf0fa
NC
2339 as_bad (_("Invalid source register for this instruction, use 'tfr'."));
2340 else if (op->reg1 == REG_NONE || op->reg1 == REG_PC)
2341 as_bad (_("Invalid source register."));
2342
2343 if (format & M6812_OP_SEX_MARKER
2344 && op->reg2 != REG_D
2345 && op->reg2 != REG_X && op->reg2 != REG_Y && op->reg2 != REG_SP)
2346 as_bad (_("Invalid destination register for this instruction, use 'tfr'."));
2347 else if (op->reg2 == REG_NONE || op->reg2 == REG_PC)
2348 as_bad (_("Invalid destination register."));
2349
2350 byte = (op->reg1 << 4) | (op->reg2);
2351 if (format & M6812_OP_EXG_MARKER)
2352 byte |= 0x80;
2353
6927f982
NC
2354 if ((format & M6812_OP_SEX_MARKER)
2355 && (op->reg1 == REG_D) && (current_architecture & cpu9s12x))
2356 byte |= 0x08;
2357
60bcf0fa
NC
2358 f = frag_more (1);
2359 number_to_chars_bigendian (f, byte, 1);
2360 return 1;
2361}
2362
6927f982
NC
2363/* build_insn_xg takes a pointer to the opcode entry in the opcode table,
2364 the array of operand expressions and builds the corresponding instruction. */
2365
2366static void
2367build_insn_xg (struct m68hc11_opcode *opcode,
2368 operand operands[],
2369 int nb_operands ATTRIBUTE_UNUSED)
2370{
2371 char *f;
2372 long format;
2373
2374 /* Put the page code instruction if there is one. */
2375 format = opcode->format;
2376
2377 if (!(operands[0].mode & (M6811_OP_LOW_ADDR | M6811_OP_HIGH_ADDR)))
2378 /* Need to retain those two modes, but clear for others. */
2379 operands[0].mode = 0;
2380
2381 if (format & M68XG_OP_R_IMM8)
2382 {
2383 /* These opcodes are byte followed by imm8. */
2384 f = m68hc11_new_insn (1);
2385 number_to_chars_bigendian (f, opcode->opcode >> 8, 1);
2386 fixup8_xg (&operands[0].exp, format, operands[0].mode);
2387 }
2388 else if (format & M68XG_OP_R_IMM16)
2389 {
2390 fixS *fixp;
2391 /* These opcodes expand into two imm8 instructions.
2392 Emit as low:high as per the Freescale datasheet.
2393 The linker requires them to be adjacent to handle the upper byte. */
2394
2395 /* Build low byte. */
2396 f = m68hc11_new_insn (1);
2397 number_to_chars_bigendian (f, opcode->opcode >> 8, 1);
2398 operands[0].mode = M6811_OP_LOW_ADDR;
2399 f = frag_more (1);
2400 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
5b7c81bd 2401 &operands[0].exp, false, BFD_RELOC_M68HC12_LO8XG);
6927f982
NC
2402 fixp->fx_no_overflow = 1;
2403 number_to_chars_bigendian (f, 0, 1);
2404
2405 /* Build high byte. */
2406 f = m68hc11_new_insn (1);
2407 number_to_chars_bigendian (f, (opcode->opcode >> 8) | 0x08, 1);
2408 operands[0].mode = M6811_OP_HIGH_ADDR;
2409 f = frag_more (1);
2410 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
5b7c81bd 2411 &operands[0].exp, false, BFD_RELOC_M68HC12_HI8XG);
6927f982
NC
2412 fixp->fx_no_overflow = 1;
2413 number_to_chars_bigendian (f, 0, 1);
2414
2415 }
2416 else if (format & M68XG_OP_REL9)
2417 {
2418 f = m68hc11_new_insn (1);
2419 number_to_chars_bigendian (f, opcode->opcode >> 8, 1); /* High byte. */
2420 fixup8_xg (&operands[0].exp, format, M68XG_OP_REL9);
3739860c 2421 }
6927f982
NC
2422 else if (format & M68XG_OP_REL10)
2423 {
2424 f = m68hc11_new_insn (1);
2425 number_to_chars_bigendian (f, opcode->opcode >> 8, 1); /* High byte. */
2426 fixup8_xg (&operands[0].exp, format, M68XG_OP_REL10);
2427 }
2428 else
2429 {
2430 f = m68hc11_new_insn (2);
2431 number_to_chars_bigendian (f, opcode->opcode, 2);
2432 }
2433 return;
2434}
2435
60bcf0fa 2436/* build_insn takes a pointer to the opcode entry in the opcode table,
67c1ffbe 2437 the array of operand expressions and builds the corresponding instruction.
60bcf0fa
NC
2438 This operation only deals with non relative jumps insn (need special
2439 handling). */
6927f982 2440
60bcf0fa 2441static void
6927f982
NC
2442build_insn (struct m68hc11_opcode *opcode,
2443 operand operands[],
ca43c854 2444 int nb_operands ATTRIBUTE_UNUSED)
60bcf0fa
NC
2445{
2446 int i;
2447 char *f;
60bcf0fa
NC
2448 long format;
2449 int move_insn = 0;
2450
2451 /* Put the page code instruction if there is one. */
2452 format = opcode->format;
e371935f 2453
e371935f 2454 if (format & M6811_OP_BRANCH)
fd99afa7 2455 fix_new (frag_now, frag_now_fix (), 0,
e371935f
SC
2456 &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
2457
60bcf0fa
NC
2458 if (format & OP_EXTENDED)
2459 {
2460 int page_code;
2461
2462 f = m68hc11_new_insn (2);
2463 if (format & M6811_OP_PAGE2)
2464 page_code = M6811_OPCODE_PAGE2;
2465 else if (format & M6811_OP_PAGE3)
2466 page_code = M6811_OPCODE_PAGE3;
2467 else
2468 page_code = M6811_OPCODE_PAGE4;
2469
2470 number_to_chars_bigendian (f, page_code, 1);
2471 f++;
60bcf0fa
NC
2472 }
2473 else
2474 f = m68hc11_new_insn (1);
2475
2476 number_to_chars_bigendian (f, opcode->opcode, 1);
2477
2478 i = 0;
2479
2480 /* The 68HC12 movb and movw instructions are special. We have to handle
2481 them in a special way. */
2482 if (format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2))
2483 {
2484 move_insn = 1;
2485 if (format & M6812_OP_IDX)
2486 {
986c6f4b 2487 build_indexed_byte (&operands[0], format, 1);
60bcf0fa
NC
2488 i = 1;
2489 format &= ~M6812_OP_IDX;
2490 }
2491 if (format & M6812_OP_IDX_P2)
2492 {
986c6f4b 2493 build_indexed_byte (&operands[1], format, 1);
60bcf0fa
NC
2494 i = 0;
2495 format &= ~M6812_OP_IDX_P2;
2496 }
2497 }
2498
2499 if (format & (M6811_OP_DIRECT | M6811_OP_IMM8))
2500 {
60bcf0fa
NC
2501 fixup8 (&operands[i].exp,
2502 format & (M6811_OP_DIRECT | M6811_OP_IMM8 | M6812_OP_TRAP_ID),
2503 operands[i].mode);
2504 i++;
2505 }
7bfda7eb
SC
2506 else if (IS_CALL_SYMBOL (format) && nb_operands == 1)
2507 {
2508 format &= ~M6812_OP_PAGE;
2509 fixup24 (&operands[i].exp, format & M6811_OP_IND16,
2510 operands[i].mode);
2511 i++;
2512 }
60bcf0fa
NC
2513 else if (format & (M6811_OP_IMM16 | M6811_OP_IND16))
2514 {
7bfda7eb
SC
2515 fixup16 (&operands[i].exp,
2516 format & (M6811_OP_IMM16 | M6811_OP_IND16 | M6812_OP_PAGE),
60bcf0fa
NC
2517 operands[i].mode);
2518 i++;
2519 }
2520 else if (format & (M6811_OP_IX | M6811_OP_IY))
2521 {
2522 if ((format & M6811_OP_IX) && (operands[0].reg1 != REG_X))
2523 as_bad (_("Invalid indexed register, expecting register X."));
2524 if ((format & M6811_OP_IY) && (operands[0].reg1 != REG_Y))
2525 as_bad (_("Invalid indexed register, expecting register Y."));
2526
60bcf0fa
NC
2527 fixup8 (&operands[0].exp, M6811_OP_IX, operands[0].mode);
2528 i = 1;
2529 }
2530 else if (format &
7bfda7eb
SC
2531 (M6812_OP_IDX | M6812_OP_IDX_2 | M6812_OP_IDX_1
2532 | M6812_OP_D_IDX | M6812_OP_D_IDX_2))
60bcf0fa 2533 {
986c6f4b 2534 build_indexed_byte (&operands[i], format, move_insn);
60bcf0fa
NC
2535 i++;
2536 }
2537 else if (format & M6812_OP_REG && current_architecture & cpu6812)
2538 {
986c6f4b 2539 build_reg_mode (&operands[i], format);
60bcf0fa
NC
2540 i++;
2541 }
2542 if (format & M6811_OP_BITMASK)
2543 {
60bcf0fa
NC
2544 fixup8 (&operands[i].exp, M6811_OP_BITMASK, operands[i].mode);
2545 i++;
2546 }
2547 if (format & M6811_OP_JUMP_REL)
2548 {
60bcf0fa 2549 fixup8 (&operands[i].exp, M6811_OP_JUMP_REL, operands[i].mode);
60bcf0fa
NC
2550 }
2551 else if (format & M6812_OP_IND16_P2)
2552 {
60bcf0fa
NC
2553 fixup16 (&operands[1].exp, M6811_OP_IND16, operands[1].mode);
2554 }
7bfda7eb
SC
2555 if (format & M6812_OP_PAGE)
2556 {
2557 fixup8 (&operands[i].exp, M6812_OP_PAGE, operands[i].mode);
2558 }
60bcf0fa 2559}
60bcf0fa
NC
2560\f
2561/* Opcode identification and operand analysis. */
2562
2563/* find() gets a pointer to an entry in the opcode table. It must look at all
2564 opcodes with the same name and use the operands to choose the correct
2565 opcode. Returns the opcode pointer if there was a match and 0 if none. */
2566static struct m68hc11_opcode *
ca43c854 2567find (struct m68hc11_opcode_def *opc, operand operands[], int nb_operands)
60bcf0fa
NC
2568{
2569 int i, match, pos;
2570 struct m68hc11_opcode *opcode;
2571 struct m68hc11_opcode *op_indirect;
2572
2573 op_indirect = 0;
2574 opcode = opc->opcode;
2575
6927f982
NC
2576 /* Now search the opcode table table for one with operands
2577 that matches what we've got. */
2578
2579 if (current_architecture & cpuxgate)
2580 {
2581 /* Many XGATE insns are simple enough that we get an exact match. */
2582 for (pos = match = 0; match == 0 && pos < opc->nb_modes; pos++, opcode++)
2583 if (opcode->format == operands[nb_operands-1].mode)
2584 return opcode;
2585
2586 return 0;
2587 }
2588
2589 /* Non XGATE */
2590
60bcf0fa
NC
2591 /* Now search the opcode table table for one with operands
2592 that matches what we've got. We're only done if the operands matched so
2593 far AND there are no more to check. */
2594 for (pos = match = 0; match == 0 && pos < opc->nb_modes; pos++, opcode++)
2595 {
2596 int poss_indirect = 0;
2597 long format = opcode->format;
2598 int expect;
2599
2600 expect = 0;
2601 if (opcode->format & M6811_OP_MASK)
2602 expect++;
2603 if (opcode->format & M6811_OP_BITMASK)
2604 expect++;
2605 if (opcode->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
2606 expect++;
2607 if (opcode->format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2))
2608 expect++;
7bfda7eb
SC
2609 if ((opcode->format & M6812_OP_PAGE)
2610 && (!IS_CALL_SYMBOL (opcode->format) || nb_operands == 2))
2611 expect++;
60bcf0fa
NC
2612
2613 for (i = 0; expect == nb_operands && i < nb_operands; i++)
2614 {
2615 int mode = operands[i].mode;
2616
2617 if (mode & M6811_OP_IMM16)
2618 {
2619 if (format &
2620 (M6811_OP_IMM8 | M6811_OP_IMM16 | M6811_OP_BITMASK))
2621 continue;
2622 break;
2623 }
2624 if (mode == M6811_OP_DIRECT)
2625 {
2626 if (format & M6811_OP_DIRECT)
2627 continue;
2628
2629 /* If the operand is a page 0 operand, remember a
2630 possible <abs-16> addressing mode. We mark
2631 this and continue to check other operands. */
2632 if (format & M6811_OP_IND16
2633 && flag_strict_direct_addressing && op_indirect == 0)
2634 {
2635 poss_indirect = 1;
2636 continue;
2637 }
2638 break;
2639 }
2640 if (mode & M6811_OP_IND16)
2641 {
2642 if (i == 0 && (format & M6811_OP_IND16) != 0)
2643 continue;
7bfda7eb
SC
2644 if (i != 0 && (format & M6812_OP_PAGE) != 0)
2645 continue;
60bcf0fa
NC
2646 if (i != 0 && (format & M6812_OP_IND16_P2) != 0)
2647 continue;
2648 if (i == 0 && (format & M6811_OP_BITMASK))
2649 break;
2650 }
2651 if (mode & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
2652 {
2653 if (format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
2654 continue;
2655 }
2656 if (mode & M6812_OP_REG)
2657 {
df86943d
NC
2658 if (i == 0
2659 && (format & M6812_OP_REG)
2660 && (operands[i].reg2 == REG_NONE))
60bcf0fa 2661 continue;
df86943d
NC
2662 if (i == 0
2663 && (format & M6812_OP_REG)
2664 && (format & M6812_OP_REG_2)
2665 && (operands[i].reg2 != REG_NONE))
60bcf0fa 2666 continue;
df86943d
NC
2667 if (i == 0
2668 && (format & M6812_OP_IDX)
2669 && (operands[i].reg2 != REG_NONE))
2670 continue;
df86943d
NC
2671 if (i == 0
2672 && (format & M6812_OP_IDX)
60bcf0fa
NC
2673 && (format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2)))
2674 continue;
df86943d
NC
2675 if (i == 1
2676 && (format & M6812_OP_IDX_P2))
60bcf0fa
NC
2677 continue;
2678 break;
2679 }
2680 if (mode & M6812_OP_IDX)
2681 {
2682 if (format & M6811_OP_IX && operands[i].reg1 == REG_X)
2683 continue;
2684 if (format & M6811_OP_IY && operands[i].reg1 == REG_Y)
2685 continue;
2686 if (i == 0
2687 && format & (M6812_OP_IDX | M6812_OP_IDX_1 | M6812_OP_IDX_2)
2688 && (operands[i].reg1 == REG_X
2689 || operands[i].reg1 == REG_Y
2690 || operands[i].reg1 == REG_SP
2691 || operands[i].reg1 == REG_PC))
2692 continue;
6927f982 2693 if (i == 1 && (format & M6812_OP_IDX_P2))
60bcf0fa
NC
2694 continue;
2695 }
7bfda7eb
SC
2696 if (mode & format & (M6812_OP_D_IDX | M6812_OP_D_IDX_2))
2697 {
2698 if (i == 0)
2699 continue;
2700 }
60bcf0fa
NC
2701 if (mode & M6812_AUTO_INC_DEC)
2702 {
2703 if (i == 0
2704 && format & (M6812_OP_IDX | M6812_OP_IDX_1 |
2705 M6812_OP_IDX_2))
2706 continue;
2707 if (i == 1 && format & M6812_OP_IDX_P2)
2708 continue;
2709 }
2710 break;
2711 }
2712 match = i == nb_operands;
2713
2714 /* Operands are ok but an operand uses page 0 addressing mode
2715 while the insn supports abs-16 mode. Keep a reference to this
2716 insns in case there is no insn supporting page 0 addressing. */
2717 if (match && poss_indirect)
2718 {
2719 op_indirect = opcode;
2720 match = 0;
2721 }
2722 if (match)
2723 break;
2724 }
2725
2726 /* Page 0 addressing is used but not supported by any insn.
2727 If absolute addresses are supported, we use that insn. */
2728 if (match == 0 && op_indirect)
2729 {
2730 opcode = op_indirect;
2731 match = 1;
2732 }
2733
6927f982 2734 return match ? opcode : 0;
60bcf0fa
NC
2735}
2736
60bcf0fa
NC
2737/* Find the real opcode and its associated operands. We use a progressive
2738 approach here. On entry, 'opc' points to the first opcode in the
2739 table that matches the opcode name in the source line. We try to
2740 isolate an operand, find a possible match in the opcode table.
2741 We isolate another operand if no match were found. The table 'operands'
2742 is filled while operands are recognized.
2743
2744 Returns the opcode pointer that matches the opcode name in the
2745 source line and the associated operands. */
2746static struct m68hc11_opcode *
ca43c854
SC
2747find_opcode (struct m68hc11_opcode_def *opc, operand operands[],
2748 int *nb_operands)
60bcf0fa
NC
2749{
2750 struct m68hc11_opcode *opcode;
2751 int i;
2752
2753 if (opc->max_operands == 0)
2754 {
2755 *nb_operands = 0;
2756 return opc->opcode;
2757 }
2758
2759 for (i = 0; i < opc->max_operands;)
2760 {
2761 int result;
2762
2763 result = get_operand (&operands[i], i, opc->format);
2764 if (result <= 0)
fafb6d17 2765 return 0;
60bcf0fa
NC
2766
2767 /* Special case where the bitmask of the bclr/brclr
2768 instructions is not introduced by #.
2769 Example: bclr 3,x $80. */
2770 if (i == 1 && (opc->format & M6811_OP_BITMASK)
2771 && (operands[i].mode & M6811_OP_IND16))
2772 {
2773 operands[i].mode = M6811_OP_IMM16;
2774 }
2775
2776 i += result;
2777 *nb_operands = i;
2778 if (i >= opc->min_operands)
2779 {
2780 opcode = find (opc, operands, i);
577300ce
SC
2781
2782 /* Another special case for 'call foo,page' instructions.
2783 Since we support 'call foo' and 'call foo,page' we must look
2784 if the optional page specification is present otherwise we will
2785 assemble immediately and treat the page spec as garbage. */
7bfda7eb
SC
2786 if (opcode && !(opcode->format & M6812_OP_PAGE))
2787 return opcode;
2788
2789 if (opcode && *input_line_pointer != ',')
fafb6d17 2790 return opcode;
60bcf0fa
NC
2791 }
2792
2793 if (*input_line_pointer == ',')
2794 input_line_pointer++;
2795 }
82efde3a 2796
60bcf0fa
NC
2797 return 0;
2798}
2799
2800#define M6812_XBCC_MARKER (M6812_OP_TBCC_MARKER \
2801 | M6812_OP_DBCC_MARKER \
2802 | M6812_OP_IBCC_MARKER)
60bcf0fa
NC
2803\f
2804/* Gas line assembler entry point. */
2805
2806/* This is the main entry point for the machine-dependent assembler. str
2807 points to a machine-dependent instruction. This function is supposed to
2808 emit the frags/bytes it assembles to. */
2809void
ca43c854 2810md_assemble (char *str)
60bcf0fa
NC
2811{
2812 struct m68hc11_opcode_def *opc;
2813 struct m68hc11_opcode *opcode;
2814
6927f982 2815 struct m68hc11_opcode opcode_local;
2132e3a3
AM
2816 unsigned char *op_start, *op_end;
2817 char *save;
60bcf0fa
NC
2818 char name[20];
2819 int nlen = 0;
2820 operand operands[M6811_MAX_OPERANDS];
878bcc43 2821 int nb_operands = 0;
60bcf0fa
NC
2822 int branch_optimize = 0;
2823 int alias_id = -1;
2824
fafb6d17 2825 /* Drop leading whitespace. */
60bcf0fa
NC
2826 while (*str == ' ')
2827 str++;
2828
2829 /* Find the opcode end and get the opcode in 'name'. The opcode is forced
2830 lower case (the opcode table only has lower case op-codes). */
2132e3a3 2831 for (op_start = op_end = (unsigned char *) str;
4ad7ac30 2832 *op_end && !is_end_of_line[*op_end] && *op_end != ' ';
60bcf0fa
NC
2833 op_end++)
2834 {
3882b010 2835 name[nlen] = TOLOWER (op_start[nlen]);
60bcf0fa 2836 nlen++;
4ad7ac30
AM
2837 if (nlen == sizeof (name) - 1)
2838 break;
60bcf0fa
NC
2839 }
2840 name[nlen] = 0;
2841
2842 if (nlen == 0)
2843 {
2844 as_bad (_("No instruction or missing opcode."));
2845 return;
2846 }
2847
6927f982
NC
2848 if (current_architecture == cpuxgate)
2849 {
2850 /* Find the opcode definition given its name. */
629310ab 2851 opc = (struct m68hc11_opcode_def *) str_hash_find (m68hc11_hash, name);
6927f982
NC
2852 if (opc == NULL)
2853 {
2854 as_bad (_("Opcode `%s' is not recognized."), name);
2855 return;
2856 }
2857
2858 /* Grab a local copy. */
2859 opcode_local.name = opc->opcode->name;
2860 /* These will be incomplete where multiple variants exist. */
2861 opcode_local.opcode = opc->opcode->opcode;
2862 opcode_local.format = opc->opcode->format;
2863
2864 save = input_line_pointer;
2865 input_line_pointer = (char *) op_end;
2866
2867 if (opc->format == M68XG_OP_NONE)
2868 {
2869 /* No special handling required. */
2870 opcode_local.format = M68XG_OP_NONE;
2871 build_insn_xg (opc->opcode, operands, 0);
2872 return;
2873 }
2874
2875 /* Special handling of TFR. */
d34049e8 2876 if (startswith (opc->opcode->name, "tfr"))
6927f982
NC
2877 {
2878 /* There must be two operands with a comma. */
2879 input_line_pointer = skip_whites (input_line_pointer);
2880 operands[0].reg1 = register_name ();
2881 if (operands[0].reg1 == REG_NONE)
2882 {
2883 as_bad ("Invalid register\n");
2884 return;
2885 }
2886 input_line_pointer = skip_whites (input_line_pointer);
2887 if (*input_line_pointer != ',')
2888 {
2889 as_bad ("Missing comma.\n");
2890 return;
2891 }
2892 input_line_pointer++;
2893 input_line_pointer = skip_whites (input_line_pointer);
2894 operands[1].reg1 = register_name ();
2895 if (operands[1].reg1 == REG_NONE)
2896 {
2897 as_bad ("Invalid register\n");
2898 return;
2899 }
2900 input_line_pointer = skip_whites (input_line_pointer);
2901 if (*input_line_pointer != '\n' && *input_line_pointer)
2902 {
2903 as_bad (_("Garbage at end of instruction: `%s'."),
2904 input_line_pointer);
2905 return;
2906 }
2907 if (operands[1].reg1 == REG_CCR) /* ,CCR */
2908 opc->opcode->opcode = 0x00f8 | ( operands[0].reg1 << 8);
2909 else if (operands[0].reg1 == REG_CCR) /* CCR, */
2910 opc->opcode->opcode = 0x00f9 | ( operands[1].reg1 << 8);
2911 else if (operands[1].reg1 == REG_PC) /* ,PC */
2912 opc->opcode->opcode = 0x00fa | ( operands[0].reg1 << 8);
2913 else
2914 {
2915 as_bad ("Invalid operand to TFR\n");
2916 return;
2917 }
2918 /* no special handling required */
2919 opcode_local.format = M68XG_OP_NONE;
2920 opcode_local.opcode = opc->opcode->opcode;
2921 build_insn_xg (&opcode_local, operands, 0);
2922 return;
2923 }
2924
2925 /* CSEM, SSEM */
2926 if (opc->format & M68XG_OP_IMM3)
2927 {
2928 /* Either IMM3 or R */
2929 input_line_pointer = skip_whites (input_line_pointer);
2930 if ((*input_line_pointer == 'R') || (*input_line_pointer == 'r'))
2931 {
2932 operands[0].reg1 = register_name ();
2933 if (operands[0].reg1 == REG_NONE)
2934 {
2935 as_bad ("Invalid register\n");
2936 return;
2937 }
2938 operands[0].mode = M68XG_OP_R;
2939 /* One opcode has multiple modes, so find right one. */
2940 opcode = find (opc, operands, 1);
2941 if (opcode)
2942 {
2943 opcode_local.opcode = opcode->opcode
2944 | (operands[0].reg1 << 8);
2945 opcode_local.format = M68XG_OP_NONE;
2946 build_insn_xg (&opcode_local, operands, 1);
2947 }
2948 else
2949 as_bad ("No opcode found\n");
3739860c 2950
6927f982
NC
2951 return;
2952 }
2953 else
2954 {
2955 if (*input_line_pointer == '#')
2956 input_line_pointer++;
2957
2958 expression (&operands[0].exp);
2959 if (operands[0].exp.X_op == O_illegal)
2960 {
2961 as_bad (_("Illegal operand."));
2962 return;
2963 }
2964 else if (operands[0].exp.X_op == O_absent)
2965 {
2966 as_bad (_("Missing operand."));
2967 return;
2968 }
2969
2970 if (check_range (operands[0].exp.X_add_number,M68XG_OP_IMM3))
2971 {
2972 opcode_local.opcode |= (operands[0].exp.X_add_number);
2973 operands[0].mode = M68XG_OP_IMM3;
3739860c 2974
6927f982
NC
2975 opcode = find (opc, operands, 1);
2976 if (opcode)
2977 {
2978 opcode_local.opcode = opcode->opcode;
2979 opcode_local.opcode
2980 |= (operands[0].exp.X_add_number) << 8;
2981 opcode_local.format = M68XG_OP_NONE;
2982 build_insn_xg (&opcode_local, operands, 1);
2983 }
2984 else
2985 as_bad ("No opcode found\n");
2986
2987 return;
2988 }
2989 else
2990 {
2991 as_bad ("Number out of range for IMM3\n");
2992 return;
2993 }
2994 }
2995 }
2996
2997 /* Special handling of SIF. */
d34049e8 2998 if (startswith (opc->opcode->name, "sif"))
6927f982
NC
2999 {
3000 /* Either OP_NONE or OP_RS. */
3001 if (*input_line_pointer != '\n')
3002 input_line_pointer = skip_whites (input_line_pointer);
3003
3004 if ((*input_line_pointer == '\n') || (*input_line_pointer == '\r')
3005 || (*input_line_pointer == '\0'))
3006 opc->opcode->opcode = 0x0300;
3007 else
3008 {
3009 operands[0].reg1 = register_name ();
3010 if (operands[0].reg1 == REG_NONE)
3011 {
3012 as_bad ("Invalid register\n");
3013 return;
3014 }
3015 opcode_local.opcode = 0x00f7 | (operands[0].reg1 << 8);
3016 }
3017 opcode_local.format = M68XG_OP_NONE;
3018 build_insn_xg (&opcode_local, operands, 0);
3019 return;
3020 }
3021
3022 /* SEX, PAR, JAL plus aliases NEG, TST, COM */
3023 if (opc->format & M68XG_OP_R)
3024 {
3025 input_line_pointer = skip_whites (input_line_pointer);
3026 operands[0].reg1 = register_name ();
3027 if (operands[0].reg1 == REG_NONE)
3028 {
3029 as_bad ("Invalid register\n");
3030 return;
3031 }
3032 if ((*input_line_pointer == '\n') || (*input_line_pointer == '\r')
3033 || (*input_line_pointer == '\0'))
3034 {
3035 /* Likely to be OP R. */
3036 if (opc->format & M68XG_OP_R)
3037 {
3038 operands[0].mode = M68XG_OP_R;
3039
3040 opcode = find (opc, operands, 1);
3041 if (opcode)
3042 {
d34049e8
ML
3043 if ((startswith (opc->opcode->name, "com"))
3044 || (startswith (opc->opcode->name, "neg")))
6927f982
NC
3045 /* Special case for com RD as alias for sub RD,R0,RS */
3046 /* Special case for neg RD as alias for sub RD,R0,RS */
3047 opcode_local.opcode = opcode->opcode
3048 | (operands[0].reg1 << 8) | (operands[0].reg1 << 2);
d34049e8 3049 else if (startswith (opc->opcode->name, "tst"))
6927f982
NC
3050 /* Special case for tst RS alias for sub R0, RS, R0 */
3051 opcode_local.opcode = opcode->opcode
3052 | (operands[0].reg1 << 5);
3053 else
3054 opcode_local.opcode |= (operands[0].reg1 << 8);
3055 }
3056 opcode_local.format = M68XG_OP_NONE;
3057 build_insn_xg (&opcode_local, operands, 0);
3058 }
3059 else
3060 as_bad ("No valid mode found\n");
3061
3062 return;
3063 }
3064 }
3065
3066 if (opc->format & (M68XG_OP_REL9 | M68XG_OP_REL10))
3067 {
3739860c 3068 opcode_local.format = opc->format;
6927f982
NC
3069 input_line_pointer = skip_whites (input_line_pointer);
3070 expression (&operands[0].exp);
3071 if (operands[0].exp.X_op == O_illegal)
3072 {
3073 as_bad (_("Illegal operand."));
3074 return;
3075 }
3076 else if (operands[0].exp.X_op == O_absent)
3077 {
3078 as_bad (_("Missing operand."));
3079 return;
3080 }
3081 opcode_local.opcode = opc->opcode->opcode;
3082 build_insn_xg (&opcode_local, operands, 1);
3083 return;
3084 }
3085
3086
3087 /* For other command formats, parse input line and determine the mode
3088 we are using as we go. */
3089
3090 input_line_pointer = skip_whites (input_line_pointer);
3091 if ((*input_line_pointer == '\n') || (*input_line_pointer == '\r')
3092 || (*input_line_pointer == '\0'))
3093 return; /* nothing left */
3739860c 3094
6927f982
NC
3095 if (*input_line_pointer == '#')
3096 {
3097 as_bad ("No register specified before hash\n");
3098 return;
3739860c 3099 }
6927f982
NC
3100
3101 /* first operand is expected to be a register */
3102 if ((*input_line_pointer == 'R') || (*input_line_pointer == 'r'))
3103 {
3104 operands[0].reg1 = register_name ();
3105 if (operands[0].reg1 == REG_NONE)
3106 {
3107 as_bad ("Invalid register\n");
3108 return;
3109 }
3110 }
3111
3112 input_line_pointer = skip_whites (input_line_pointer);
3113 if (*input_line_pointer != ',')
3114 {
3115 as_bad ("Missing operand\n");
3116 return;
3117 }
3118 input_line_pointer++;
3119 input_line_pointer = skip_whites (input_line_pointer);
3120
3121 if (*input_line_pointer == '#')
3122 {
3123 /* Some kind of immediate mode, check if this is possible. */
3124 if (!(opc->format
3125 & (M68XG_OP_R_IMM8 | M68XG_OP_R_IMM16 | M68XG_OP_R_IMM4)))
3126 as_bad ("Invalid immediate mode for `%s'", opc->opcode->name);
3127 else
3128 {
3129 input_line_pointer++;
3130 input_line_pointer = skip_whites (input_line_pointer);
d34049e8 3131 if (startswith (input_line_pointer, "%hi"))
6927f982
NC
3132 {
3133 input_line_pointer += 3;
3134 operands[0].mode = M6811_OP_HIGH_ADDR;
3135 }
d34049e8 3136 else if (startswith (input_line_pointer, "%lo"))
6927f982
NC
3137 {
3138 input_line_pointer += 3;
3139 operands[0].mode = M6811_OP_LOW_ADDR;
3140 }
3141 else
3142 operands[0].mode = 0;
3143
3144 expression (&operands[0].exp);
3145 if (operands[0].exp.X_op == O_illegal)
3146 {
3147 as_bad (_("Illegal operand."));
3148 return;
3149 }
3150 else if (operands[0].exp.X_op == O_absent)
3151 {
3152 as_bad (_("Missing operand."));
3153 return;
3154 }
3155 /* ok so far, can only be one mode */
3156 opcode_local.format = opc->format
3157 & (M68XG_OP_R_IMM8 | M68XG_OP_R_IMM16 | M68XG_OP_R_IMM4);
3158 if (opcode_local.format & M68XG_OP_R_IMM4)
3159 {
3160 operands[0].mode = M68XG_OP_R_IMM4;
3161 /* same opcodes have multiple modes, so find right one */
3162 opcode = find (opc, operands, 1);
3163 if (opcode)
3164 opcode_local.opcode = opcode->opcode
3165 | (operands[0].reg1 << 8);
3739860c 3166
6927f982
NC
3167 if (operands[0].exp.X_op != O_constant)
3168 as_bad ("Only constants supported at for IMM4 mode\n");
3169 else
3170 {
3739860c 3171 if (check_range
6927f982
NC
3172 (operands[0].exp.X_add_number,M68XG_OP_R_IMM4))
3173 opcode_local.opcode
3174 |= (operands[0].exp.X_add_number << 4);
3175 else
3176 as_bad ("Number out of range for IMM4\n");
3177 }
3178 opcode_local.format = M68XG_OP_NONE;
3179 }
3180 else if (opcode_local.format & M68XG_OP_R_IMM16)
3181 {
3182 operands[0].mode = M68XG_OP_R_IMM16;
3183
3184 opcode = find (opc, operands, 1);
3185 if (opcode)
3186 {
3187 opcode_local.opcode = opcode->opcode
3188 | (operands[0].reg1 << 8);
3189 }
3190 }
3191 else
3192 {
3193 opcode_local.opcode = opc->opcode->opcode
3194 | (operands[0].reg1 << 8);
3195 }
3196 build_insn_xg (&opcode_local, operands, 1);
3197 }
3198 }
3199 else if ((*input_line_pointer == 'R') || (*input_line_pointer == 'r'))
3200 {
3201 /* we've got as far as OP R, R */
3202 operands[1].reg1 = register_name ();
3203 if (operands[1].reg1 == REG_NONE)
3204 {
3205 as_bad ("Invalid register\n");
3206 return;
3207 }
3208 if ((*input_line_pointer == '\n') || (*input_line_pointer == '\r')
3209 || (*input_line_pointer == '\0'))
3210 {
3211 /* looks like OP_R_R */
3212 if (opc->format & M68XG_OP_R_R)
3213 {
3214 operands[0].mode = M68XG_OP_R_R;
3215 /* same opcodes have multiple modes, so find right one */
3216 opcode = find (opc, operands, 1);
3217 if (opcode)
3218 {
d34049e8
ML
3219 if ((startswith (opc->opcode->name, "com"))
3220 || (startswith (opc->opcode->name, "mov"))
3221 || (startswith (opc->opcode->name, "neg")))
6927f982
NC
3222 {
3223 /* Special cases for:
3224 com RD, RS alias for xnor RD,R0,RS
3225 mov RD, RS alias for or RD, R0, RS
3226 neg RD, RS alias for sub RD, R0, RS */
3739860c 3227 opcode_local.opcode = opcode->opcode
6927f982
NC
3228 | (operands[0].reg1 << 8) | (operands[1].reg1 << 2);
3229 }
d34049e8
ML
3230 else if ((startswith (opc->opcode->name, "cmp"))
3231 || (startswith (opc->opcode->name, "cpc")))
6927f982
NC
3232 {
3233 /* special cases for:
3234 cmp RS1, RS2 alias for sub R0, RS1, RS2
3235 cpc RS1, RS2 alias for sbc R0, RS1, RS2 */
3739860c 3236 opcode_local.opcode = opcode->opcode
6927f982
NC
3237 | (operands[0].reg1 << 5) | (operands[1].reg1 << 2);
3238 }
3239 else
3240 {
3241 opcode_local.opcode = opcode->opcode
3242 | (operands[0].reg1 << 8) | (operands[1].reg1 << 5);
3243 }
3244 opcode_local.format = M68XG_OP_NONE;
3245 build_insn_xg (&opcode_local, operands, 1);
3246 }
3247 }
3248 else
3249 {
3250 as_bad ("No valid mode found\n");
3251 }
3252 }
3253 else
3254 {
3255 /* more data */
3256 if (*input_line_pointer != ',')
3257 {
3258 as_bad (_("Missing operand."));
3259 return;
3260 }
3261 input_line_pointer++;
3262 input_line_pointer = skip_whites (input_line_pointer);
3263 if ((*input_line_pointer == 'R') || (*input_line_pointer == 'r'))
3264 {
3265 operands[2].reg1 = register_name ();
3266 if (operands[2].reg1 == REG_NONE)
3267 {
3268 as_bad ("Invalid register\n");
3269 return;
3270 }
3271 if (opc->format & M68XG_OP_R_R_R)
3272 {
3273 operands[0].mode = M68XG_OP_R_R_R;
3274
3275 opcode = find (opc, operands, 1);
3276 if (opcode)
3277 {
3739860c 3278 opcode_local.opcode = opcode->opcode
6927f982
NC
3279 | (operands[0].reg1 << 8) | (operands[1].reg1 << 5)
3280 | (operands[2].reg1 << 2);
3281 opcode_local.format = M68XG_OP_NONE;
3282 build_insn_xg (&opcode_local, operands, 1);
3283 }
3284 }
3285 else
3286 {
3287 as_bad ("No valid mode found\n");
3288 }
3289 }
3290 }
3291 }
3292 else if (*input_line_pointer == '(') /* Indexed modes */
3293 {
3294 input_line_pointer++;
3295 input_line_pointer = skip_whites (input_line_pointer);
3296 if ((*input_line_pointer == 'R') || (*input_line_pointer == 'r'))
3297 {
3298 /* we've got as far as OP R, (R */
3299 operands[1].reg1 = register_name ();
3300 if (operands[1].reg1 == REG_NONE)
3301 {
3302 as_bad ("Invalid register\n");
3303 return;
3304 }
3305
3306 if ((*input_line_pointer == '\n') || (*input_line_pointer == '\r')
3307 || (*input_line_pointer == '\0'))
3308 {
3309 /* Looks like OP_R_R. */
3310 as_bad (_("Missing operand."));
3311 return;
3312 }
3313
3314 input_line_pointer = skip_whites (input_line_pointer);
3739860c 3315
6927f982
NC
3316 if (*input_line_pointer != ',')
3317 {
3318 as_bad (_("Missing operand."));
3319 return;
3320 }
3321 input_line_pointer++;
3322 input_line_pointer = skip_whites (input_line_pointer);
3323
3324 if (*input_line_pointer == '#')
3325 {
3326 input_line_pointer++;
3327 input_line_pointer = skip_whites (input_line_pointer);
3328 expression (&operands[0].exp);
3329 if (operands[0].exp.X_op == O_illegal)
3330 {
3331 as_bad (_("Illegal operand."));
3332 return;
3333 }
3334 else if (operands[0].exp.X_op == O_absent)
3335 {
3336 as_bad (_("Missing operand."));
3337 return;
3338 }
3339
3340 input_line_pointer = skip_whites (input_line_pointer);
3341 if (*input_line_pointer != ')')
3342 {
3343 as_bad ("Missing `)' to close register indirect operand.");
3344 return;
3345 }
3346 else
3347 {
3348 input_line_pointer++;
3349 }
3739860c 3350
6927f982
NC
3351 /* Ok so far, can only be one mode. */
3352 opcode_local.format = M68XG_OP_R_R_OFFS5;
3353 operands[0].mode = M68XG_OP_R_R_OFFS5;
3354
3355 opcode = find (opc, operands, 1);
3356 if (opcode)
3357 {
3358 opcode_local.opcode = opcode->opcode
3359 | (operands[0].reg1 << 8) | (operands[1].reg1 << 5);
3360 if (operands[0].exp.X_op != O_constant)
3361 {
3362 as_bad
3363 ("Only constants supported for indexed OFFS5 mode\n");
3364 }
3365 else
3366 {
3367 if (check_range (operands[0].exp.X_add_number,
3368 M68XG_OP_R_R_OFFS5))
3369 {
3370 opcode_local.opcode
3371 |= (operands[0].exp.X_add_number);
3372 opcode_local.format = M68XG_OP_NONE;
3373 build_insn_xg (&opcode_local, operands, 1);
3374 }
3375 else
3376 {
3377 as_bad ("Number out of range for OFFS5\n");
3378 }
3379 }
3380 }
3381 }
3382 else
3383 {
3384 operands[0].mode = M68XG_OP_RD_RB_RI;
3385
3386 if (*input_line_pointer == '-')
3387 {
3388 operands[0].mode = M68XG_OP_RD_RB_mRI;
3389 input_line_pointer++;
3390 }
3391 operands[2].reg1 = register_name ();
3392 if (operands[2].reg1 == REG_NONE)
3393 {
3394 as_bad ("Invalid register\n");
3395 return;
3396 }
3397
3398 if (*input_line_pointer == '+')
3399 {
3400 if (opcode_local.format == M68XG_OP_RD_RB_mRI)
3401 {
3402 as_bad (_("Illegal operand."));
3403 return;
3404 }
3405 operands[0].mode = M68XG_OP_RD_RB_RIp;
3406 input_line_pointer++;
3407 }
3408
3409 input_line_pointer = skip_whites (input_line_pointer);
3410 if (*input_line_pointer != ')')
3411 {
3412 as_bad
3413 ("Missing `)' to close register indirect operand.");
3414 return;
3415 }
3416 else
3417 {
3418 input_line_pointer++;
3419 }
3420
3421 opcode = find (opc, operands, 1);
3422 if (opcode)
3423 {
3424 opcode_local.opcode = opcode->opcode
3425 | (operands[0].reg1 << 8) | (operands[1].reg1 << 5)
3426 | (operands[2].reg1 << 2);
3427 opcode_local.format = M68XG_OP_NONE;
3428 build_insn_xg (&opcode_local, operands, 1);
3429 }
3430 else
3431 {
3432 as_bad ("Failed to find opcode for %s %s\n",
3433 opc->opcode->name, (char *)op_end);
3434 }
3435 }
3436 }
3437 }
3438 else
3439 {
3440 as_bad (_("Failed to find a valid mode for `%s'."),
3441 opc->opcode->name);
3442 }
3443
3444 if (opc->opcode && !flag_mri)
3445 {
3446 char *p = input_line_pointer;
3447
3448 while (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r')
3449 p++;
3450
3451 if (*p != '\n' && *p)
3452 as_bad (_("Garbage at end of instruction: `%s'."), p);
3453 }
3454
3455 input_line_pointer = save;
3456
3457 /* Opcode is known but does not have valid operands. Print out the
3458 syntax for this opcode. */
3459 if (opc->opcode == 0)
3460 {
3461 if (flag_print_insn_syntax)
3462 print_insn_format (name);
3463
3464 as_bad (_("Invalid operand for `%s'"), name);
3465 return;
3466 }
3467
3468 return;
3469 }
3470
60bcf0fa 3471 /* Find the opcode definition given its name. */
629310ab 3472 opc = (struct m68hc11_opcode_def *) str_hash_find (m68hc11_hash, name);
60bcf0fa
NC
3473
3474 /* If it's not recognized, look for 'jbsr' and 'jbxx'. These are
1370e33d
NC
3475 pseudo insns for relative branch. For these branches, we always
3476 optimize them (turned into absolute branches) even if --short-branches
60bcf0fa
NC
3477 is given. */
3478 if (opc == NULL && name[0] == 'j' && name[1] == 'b')
3479 {
fe0e921f
AM
3480 opc = (struct m68hc11_opcode_def *) str_hash_find (m68hc11_hash,
3481 &name[1]);
60bcf0fa
NC
3482 if (opc
3483 && (!(opc->format & M6811_OP_JUMP_REL)
3484 || (opc->format & M6811_OP_BITMASK)))
3485 opc = 0;
3486 if (opc)
3487 branch_optimize = 1;
3488 }
3489
6927f982 3490 /* The following test should probably be removed. This does not conform
60bcf0fa
NC
3491 to Motorola assembler specs. */
3492 if (opc == NULL && flag_mri)
3493 {
3494 if (*op_end == ' ' || *op_end == '\t')
3495 {
3496 while (*op_end == ' ' || *op_end == '\t')
3497 op_end++;
3498
3499 if (nlen < 19
3500 && (*op_end &&
3501 (is_end_of_line[op_end[1]]
3502 || op_end[1] == ' ' || op_end[1] == '\t'
3882b010 3503 || !ISALNUM (op_end[1])))
60bcf0fa
NC
3504 && (*op_end == 'a' || *op_end == 'b'
3505 || *op_end == 'A' || *op_end == 'B'
3506 || *op_end == 'd' || *op_end == 'D'
3507 || *op_end == 'x' || *op_end == 'X'
3508 || *op_end == 'y' || *op_end == 'Y'))
3509 {
3882b010 3510 name[nlen++] = TOLOWER (*op_end++);
60bcf0fa 3511 name[nlen] = 0;
629310ab 3512 opc = (struct m68hc11_opcode_def *) str_hash_find (m68hc11_hash,
fe0e921f 3513 name);
60bcf0fa
NC
3514 }
3515 }
3516 }
3517
3518 /* Identify a possible instruction alias. There are some on the
986c6f4b 3519 68HC12 to emulate a few 68HC11 instructions. */
60bcf0fa
NC
3520 if (opc == NULL && (current_architecture & cpu6812))
3521 {
3522 int i;
3523
3524 for (i = 0; i < m68hc12_num_alias; i++)
3525 if (strcmp (m68hc12_alias[i].name, name) == 0)
3526 {
3527 alias_id = i;
3528 break;
3529 }
3530 }
3531 if (opc == NULL && alias_id < 0)
3532 {
3533 as_bad (_("Opcode `%s' is not recognized."), name);
3534 return;
3535 }
3536 save = input_line_pointer;
2132e3a3 3537 input_line_pointer = (char *) op_end;
60bcf0fa
NC
3538
3539 if (opc)
3540 {
3541 opc->used++;
3542 opcode = find_opcode (opc, operands, &nb_operands);
3543 }
3544 else
3545 opcode = 0;
3546
3547 if ((opcode || alias_id >= 0) && !flag_mri)
3548 {
3549 char *p = input_line_pointer;
3550
3551 while (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r')
3552 p++;
3553
3554 if (*p != '\n' && *p)
3555 as_bad (_("Garbage at end of instruction: `%s'."), p);
3556 }
3557
3558 input_line_pointer = save;
3559
3560 if (alias_id >= 0)
3561 {
3562 char *f = m68hc11_new_insn (m68hc12_alias[alias_id].size);
fafb6d17 3563
60bcf0fa
NC
3564 number_to_chars_bigendian (f, m68hc12_alias[alias_id].code1, 1);
3565 if (m68hc12_alias[alias_id].size > 1)
3566 number_to_chars_bigendian (f + 1, m68hc12_alias[alias_id].code2, 1);
3567
3568 return;
3569 }
3570
3571 /* Opcode is known but does not have valid operands. Print out the
3572 syntax for this opcode. */
3573 if (opcode == 0)
3574 {
3575 if (flag_print_insn_syntax)
3576 print_insn_format (name);
3577
6927f982
NC
3578 if (((strcmp (name, "movb") == 0) || (strcmp (name, "movw") == 0))
3579 && (current_architecture & cpu9s12x))
3580 {
3581 char *f;
3582 int movb;
3583 if (strcmp (name, "movb") == 0)
3584 movb = 8;
3585 else
3586 movb = 0;
3587
3588 /* The existing operand extract code fell over if these additional modes
3589 were enabled in m68hc11-opc.c. So they are commented there and
3590 decoded here instead. */
3591
3592 if (operands[1].mode & (M6812_OP_IDX | M6812_OP_IDX_1
3593 | M6812_OP_IDX_2 | M6812_OP_D_IDX | M6812_OP_D_IDX_2 | M6812_PRE_INC
3594 | M6812_PRE_DEC | M6812_POST_INC | M6812_POST_DEC ))
3595 {
3596 /* first check if valid mode then start building it up */
3597 if (operands[0].mode & (M6811_OP_IMM8 | M6811_OP_IMM16
3598 | M6811_OP_IND16 | M6812_OP_IDX | M6812_OP_IDX_1
3599 | M6812_OP_IDX_2 | M6812_OP_D_IDX | M6812_OP_D_IDX_2))
3600 {
3601 int opr16a;
3602 if (operands[1].mode & (M6811_OP_IND16))
3603 opr16a = 3;
3604 else
3605 opr16a = 0;
3606
3607 f = m68hc11_new_insn (2);
3608
3609 if (operands[0].mode & (M6811_OP_IMM8 | M6811_OP_IMM16))
3610 {
3611 number_to_chars_bigendian (f, 0x1800 + movb + opr16a, 2);
3612 build_indexed_byte (&operands[1], operands[1].mode, 1);
3613 if (movb)
3614 fixup8 (&operands[0].exp, M6811_OP_IMM8,
3615 operands[0].mode);
3616 else
3617 fixup16 (&operands[0].exp, M6811_OP_IMM16,
3618 operands[0].mode);
3619
3620 return;
3621 }
3622 else if (operands[0].mode & M6811_OP_IND16)
3623 {
3624 number_to_chars_bigendian (f, 0x1801 + movb + opr16a, 2);
3625 build_indexed_byte (&operands[1], operands[1].mode, 1);
3626 fixup16 (&operands[0].exp, M6811_OP_IND16, operands[0].mode);
3627 return;
3628 }
3629 else
3630 {
3631 number_to_chars_bigendian (f, 0x1802 + movb + opr16a, 2);
3632 build_indexed_byte (&operands[0], operands[0].mode, 1);
3633 build_indexed_byte (&operands[1], operands[1].mode, 1);
3634 return;
3635 }
3636 }
3637 }
3638 else if (operands[1].mode & M6811_OP_IND16)
3639 {
3640 /* First check if this is valid mode, then start building it up. */
3641 if (operands[0].mode & (M6811_OP_IMM8 | M6811_OP_IMM16
3642 | M6811_OP_IND16 | M6812_OP_IDX | M6812_OP_IDX_1
3643 | M6812_OP_IDX_2 | M6812_OP_D_IDX | M6812_OP_D_IDX_2))
3644 {
3645 int opr16a;
3646 if (operands[1].mode & (M6811_OP_IND16))
3647 opr16a = 3;
3648 else
3649 opr16a = 0;
3650
3651 f = m68hc11_new_insn (2);
3652
3653 /* The first two cases here should actually be covered by the
3654 normal operand code. */
3655 if (operands[0].mode & (M6811_OP_IMM8 | M6811_OP_IMM16))
3656 {
3657 number_to_chars_bigendian (f, 0x1800 + movb + opr16a, 2);
3658 if (movb)
3659 fixup8 (&operands[0].exp, M6811_OP_IMM8, operands[0].mode);
3660 else
3661 fixup16 (&operands[0].exp, M6811_OP_IMM16, operands[0].mode);
3662
3663 fixup16 (&operands[0].exp, M6811_OP_IND16, operands[0].mode);
3664 return;
3665 }
3666 else if (operands[0].mode & M6811_OP_IND16)
3667 {
3668 number_to_chars_bigendian (f, 0x1801 + movb + opr16a, 2);
3669 build_indexed_byte (&operands[1], operands[1].mode, 1);
3670 fixup16 (&operands[0].exp, M6811_OP_IND16, operands[0].mode);
3671 return;
3672 }
3673 else
3674 {
3675 number_to_chars_bigendian (f, 0x1802 + movb + opr16a, 2);
3676 build_indexed_byte (&operands[0], operands[0].mode, 1);
3677 fixup16 (&operands[1].exp, M6811_OP_IND16, operands[1].mode);
3678 return;
3679 }
3680 }
3681 }
3682
3683 as_bad (_("Invalid operand for `%s'"), name);
3684 return;
3685
3686 }
3687 else
3688 {
3689 as_bad (_("Invalid operand for `%s'"), name);
3690 return;
3691 }
60bcf0fa
NC
3692 }
3693
3694 /* Treat dbeq/ibeq/tbeq instructions in a special way. The branch is
3695 relative and must be in the range -256..255 (9-bits). */
3696 if ((opcode->format & M6812_XBCC_MARKER)
3697 && (opcode->format & M6811_OP_JUMP_REL))
27302d63 3698 build_dbranch_insn (opcode, operands, nb_operands, branch_optimize);
60bcf0fa
NC
3699
3700 /* Relative jumps instructions are taken care of separately. We have to make
3701 sure that the relative branch is within the range -128..127. If it's out
3702 of range, the instructions are changed into absolute instructions.
3703 This is not supported for the brset and brclr instructions. */
3704 else if ((opcode->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
3705 && !(opcode->format & M6811_OP_BITMASK))
3706 build_jump_insn (opcode, operands, nb_operands, branch_optimize);
3707 else
3708 build_insn (opcode, operands, nb_operands);
3709}
eb086b59
SC
3710
3711\f
3712/* Pseudo op to control the ELF flags. */
3713static void
ca43c854 3714s_m68hc11_mode (int x ATTRIBUTE_UNUSED)
eb086b59
SC
3715{
3716 char *name = input_line_pointer, ch;
3717
3718 while (!is_end_of_line[(unsigned char) *input_line_pointer])
3719 input_line_pointer++;
3720 ch = *input_line_pointer;
3721 *input_line_pointer = '\0';
3722
3723 if (strcmp (name, "mshort") == 0)
3724 {
3725 elf_flags &= ~E_M68HC11_I32;
3726 }
3727 else if (strcmp (name, "mlong") == 0)
3728 {
3729 elf_flags |= E_M68HC11_I32;
3730 }
3731 else if (strcmp (name, "mshort-double") == 0)
3732 {
3733 elf_flags &= ~E_M68HC11_F64;
3734 }
3735 else if (strcmp (name, "mlong-double") == 0)
3736 {
3737 elf_flags |= E_M68HC11_F64;
3738 }
3739 else
3740 {
3741 as_warn (_("Invalid mode: %s\n"), name);
3742 }
3743 *input_line_pointer = ch;
3744 demand_empty_rest_of_line ();
3745}
3746
3747/* Mark the symbols with STO_M68HC12_FAR to indicate the functions
3748 are using 'rtc' for returning. It is necessary to use 'call'
3749 to invoke them. This is also used by the debugger to correctly
3750 find the stack frame. */
3751static void
ca43c854 3752s_m68hc11_mark_symbol (int mark)
eb086b59
SC
3753{
3754 char *name;
3755 int c;
3756 symbolS *symbolP;
3757 asymbol *bfdsym;
3758 elf_symbol_type *elfsym;
3759
3760 do
3761 {
d02603dc 3762 c = get_symbol_name (&name);
eb086b59 3763 symbolP = symbol_find_or_make (name);
d02603dc 3764 (void) restore_line_pointer (c);
eb086b59
SC
3765
3766 SKIP_WHITESPACE ();
3767
3768 bfdsym = symbol_get_bfdsym (symbolP);
c1229f84 3769 elfsym = elf_symbol_from (bfdsym);
eb086b59 3770
9c2799c2 3771 gas_assert (elfsym);
eb086b59
SC
3772
3773 /* Mark the symbol far (using rtc for function return). */
3774 elfsym->internal_elf_sym.st_other |= mark;
3775
3776 if (c == ',')
3777 {
3778 input_line_pointer ++;
3779
3780 SKIP_WHITESPACE ();
3781
3782 if (*input_line_pointer == '\n')
3783 c = '\n';
3784 }
3785 }
3786 while (c == ',');
3787
3788 demand_empty_rest_of_line ();
3789}
e371935f
SC
3790
3791static void
ca43c854 3792s_m68hc11_relax (int ignore ATTRIBUTE_UNUSED)
e371935f
SC
3793{
3794 expressionS ex;
3795
3796 expression (&ex);
3797
3798 if (ex.X_op != O_symbol || ex.X_add_number != 0)
3799 {
3800 as_bad (_("bad .relax format"));
3801 ignore_rest_of_line ();
3802 return;
3803 }
3804
fd99afa7 3805 fix_new_exp (frag_now, frag_now_fix (), 0, &ex, 1,
e371935f
SC
3806 BFD_RELOC_M68HC11_RL_GROUP);
3807
3808 demand_empty_rest_of_line ();
3809}
3810
60bcf0fa
NC
3811\f
3812/* Relocation, relaxation and frag conversions. */
e371935f
SC
3813
3814/* PC-relative offsets are relative to the start of the
3815 next instruction. That is, the address of the offset, plus its
3816 size, since the offset is always the last part of the insn. */
60bcf0fa 3817long
ca43c854 3818md_pcrel_from (fixS *fixP)
60bcf0fa 3819{
e371935f 3820 if (fixP->fx_r_type == BFD_RELOC_M68HC11_RL_JUMP)
60bcf0fa
NC
3821 return 0;
3822
e371935f 3823 return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
60bcf0fa
NC
3824}
3825
3826/* If while processing a fixup, a reloc really needs to be created
3827 then it is done here. */
3828arelent *
ca43c854 3829tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
60bcf0fa
NC
3830{
3831 arelent *reloc;
3832
add39d23
TS
3833 reloc = XNEW (arelent);
3834 reloc->sym_ptr_ptr = XNEW (asymbol *);
60bcf0fa
NC
3835 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
3836 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
3837 if (fixp->fx_r_type == 0)
3838 reloc->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_16);
3839 else
3840 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
3841 if (reloc->howto == (reloc_howto_type *) NULL)
3842 {
3843 as_bad_where (fixp->fx_file, fixp->fx_line,
3844 _("Relocation %d is not supported by object file format."),
3845 (int) fixp->fx_r_type);
3846 return NULL;
3847 }
3848
a161fe53
AM
3849 /* Since we use Rel instead of Rela, encode the vtable entry to be
3850 used in the relocation's section offset. */
3851 if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
3852 reloc->address = fixp->fx_offset;
3853
3854 reloc->addend = 0;
60bcf0fa
NC
3855 return reloc;
3856}
3857
c9e03e8b
SC
3858/* We need a port-specific relaxation function to cope with sym2 - sym1
3859 relative expressions with both symbols in the same segment (but not
3860 necessarily in the same frag as this insn), for example:
3861 ldab sym2-(sym1-2),pc
3862 sym1:
3863 The offset can be 5, 9 or 16 bits long. */
3864
3865long
ca43c854
SC
3866m68hc11_relax_frag (segT seg ATTRIBUTE_UNUSED, fragS *fragP,
3867 long stretch ATTRIBUTE_UNUSED)
c9e03e8b
SC
3868{
3869 long growth;
3870 offsetT aim = 0;
3871 symbolS *symbolP;
3872 const relax_typeS *this_type;
3873 const relax_typeS *start_type;
3874 relax_substateT next_state;
3875 relax_substateT this_state;
3876 const relax_typeS *table = TC_GENERIC_RELAX_TABLE;
3877
3878 /* We only have to cope with frags as prepared by
33eaf5de 3879 md_estimate_size_before_relax. The STATE_BITS16 case may get here
c9e03e8b
SC
3880 because of the different reasons that it's not relaxable. */
3881 switch (fragP->fr_subtype)
3882 {
75538612 3883 case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS16):
c9e03e8b
SC
3884 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16):
3885 /* When we get to this state, the frag won't grow any more. */
3886 return 0;
3887
75538612 3888 case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS5):
c9e03e8b 3889 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS5):
75538612 3890 case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS9):
c9e03e8b
SC
3891 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9):
3892 if (fragP->fr_symbol == NULL
3893 || S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
3894 as_fatal (_("internal inconsistency problem in %s: fr_symbol %lx"),
4981a31d 3895 __func__, (long) fragP->fr_symbol);
c9e03e8b
SC
3896 symbolP = fragP->fr_symbol;
3897 if (symbol_resolved_p (symbolP))
3898 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
4981a31d 3899 __func__);
c9e03e8b
SC
3900 aim = S_GET_VALUE (symbolP);
3901 break;
3902
3903 default:
3904 as_fatal (_("internal inconsistency problem in %s: fr_subtype %d"),
4981a31d 3905 __func__, fragP->fr_subtype);
c9e03e8b
SC
3906 }
3907
3908 /* The rest is stolen from relax_frag. There's no obvious way to
3909 share the code, but fortunately no requirement to keep in sync as
3910 long as fragP->fr_symbol does not have its segment changed. */
3911
3912 this_state = fragP->fr_subtype;
3913 start_type = this_type = table + this_state;
3914
3915 if (aim < 0)
3916 {
3917 /* Look backwards. */
3918 for (next_state = this_type->rlx_more; next_state;)
3919 if (aim >= this_type->rlx_backward)
3920 next_state = 0;
3921 else
3922 {
3923 /* Grow to next state. */
3924 this_state = next_state;
3925 this_type = table + this_state;
3926 next_state = this_type->rlx_more;
3927 }
3928 }
3929 else
3930 {
3931 /* Look forwards. */
3932 for (next_state = this_type->rlx_more; next_state;)
3933 if (aim <= this_type->rlx_forward)
3934 next_state = 0;
3935 else
3936 {
3937 /* Grow to next state. */
3938 this_state = next_state;
3939 this_type = table + this_state;
3940 next_state = this_type->rlx_more;
3941 }
3942 }
3943
3944 growth = this_type->rlx_length - start_type->rlx_length;
3945 if (growth != 0)
3946 fragP->fr_subtype = this_state;
3947 return growth;
3948}
3949
60bcf0fa 3950void
ca43c854
SC
3951md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, asection *sec ATTRIBUTE_UNUSED,
3952 fragS *fragP)
60bcf0fa 3953{
88051039 3954 long value;
60bcf0fa
NC
3955 long disp;
3956 char *buffer_address = fragP->fr_literal;
3957
3958 /* Address in object code of the displacement. */
ed9e98c2 3959 int object_address = fragP->fr_fix + fragP->fr_address;
60bcf0fa
NC
3960
3961 buffer_address += fragP->fr_fix;
3962
3963 /* The displacement of the address, from current location. */
ac62c346 3964 value = S_GET_VALUE (fragP->fr_symbol);
88051039 3965 disp = (value + fragP->fr_offset) - object_address;
60bcf0fa
NC
3966
3967 switch (fragP->fr_subtype)
3968 {
3969 case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE):
3970 fragP->fr_opcode[1] = disp;
3971 break;
3972
3973 case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD):
3974 /* This relax is only for bsr and bra. */
9c2799c2 3975 gas_assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
60bcf0fa
NC
3976 || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
3977 || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
3978
3979 fragP->fr_opcode[0] = convert_branch (fragP->fr_opcode[0]);
3980
3981 fix_new (fragP, fragP->fr_fix - 1, 2,
3982 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
3983 fragP->fr_fix += 1;
3984 break;
3985
3986 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_BYTE):
3987 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_BYTE):
3988 fragP->fr_opcode[1] = disp;
3989 break;
3990
3991 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_WORD):
3992 /* Invert branch. */
3993 fragP->fr_opcode[0] ^= 1;
fafb6d17 3994 fragP->fr_opcode[1] = 3; /* Branch offset. */
60bcf0fa
NC
3995 buffer_address[0] = M6811_JMP;
3996 fix_new (fragP, fragP->fr_fix + 1, 2,
3997 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
3998 fragP->fr_fix += 3;
3999 break;
4000
4001 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_WORD):
4002 /* Translate branch into a long branch. */
4003 fragP->fr_opcode[1] = fragP->fr_opcode[0];
4004 fragP->fr_opcode[0] = M6811_OPCODE_PAGE2;
4005
9798e45d
SK
4006 fix_new (fragP, fragP->fr_fix, 2,
4007 fragP->fr_symbol, fragP->fr_offset, 1,
60bcf0fa 4008 BFD_RELOC_16_PCREL);
60bcf0fa
NC
4009 fragP->fr_fix += 2;
4010 break;
4011
75538612
SC
4012 case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS5):
4013 if (fragP->fr_symbol != 0
c9e03e8b
SC
4014 && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
4015 value = disp;
75538612
SC
4016 /* fall through */
4017
4018 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS5):
88051039 4019 fragP->fr_opcode[0] = fragP->fr_opcode[0] << 6;
c9e03e8b 4020 fragP->fr_opcode[0] |= value & 0x1f;
60bcf0fa
NC
4021 break;
4022
75538612
SC
4023 case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS9):
4024 /* For a PC-relative offset, use the displacement with a -1 correction
4025 to take into account the additional byte of the insn. */
4026 if (fragP->fr_symbol != 0
c9e03e8b 4027 && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
75538612
SC
4028 value = disp - 1;
4029 /* fall through */
4030
4031 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9):
60bcf0fa
NC
4032 fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3);
4033 fragP->fr_opcode[0] |= 0xE0;
c9e03e8b
SC
4034 fragP->fr_opcode[0] |= (value >> 8) & 1;
4035 fragP->fr_opcode[1] = value;
60bcf0fa
NC
4036 fragP->fr_fix += 1;
4037 break;
4038
75538612 4039 case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS16):
60bcf0fa
NC
4040 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16):
4041 fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3);
88051039 4042 fragP->fr_opcode[0] |= 0xe2;
c9e03e8b
SC
4043 if ((fragP->fr_opcode[0] & 0x0ff) == 0x0fa
4044 && fragP->fr_symbol != 0
4045 && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
098f2ec3 4046 {
9798e45d
SK
4047 fix_new (fragP, fragP->fr_fix, 2,
4048 fragP->fr_symbol, fragP->fr_offset,
4049 1, BFD_RELOC_16_PCREL);
098f2ec3 4050 }
88051039 4051 else
098f2ec3
KH
4052 {
4053 fix_new (fragP, fragP->fr_fix, 2,
4054 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
4055 }
88051039 4056 fragP->fr_fix += 2;
60bcf0fa
NC
4057 break;
4058
4059 case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_BYTE):
4060 if (disp < 0)
4061 fragP->fr_opcode[0] |= 0x10;
4062
4063 fragP->fr_opcode[1] = disp & 0x0FF;
4064 break;
4065
4066 case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_WORD):
4067 /* Invert branch. */
4068 fragP->fr_opcode[0] ^= 0x20;
4069 fragP->fr_opcode[1] = 3; /* Branch offset. */
4070 buffer_address[0] = M6812_JMP;
4071 fix_new (fragP, fragP->fr_fix + 1, 2,
4072 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
4073 fragP->fr_fix += 3;
4074 break;
4075
4076 default:
4077 break;
4078 }
4079}
4080
dbb8ad49
SC
4081/* On an ELF system, we can't relax a weak symbol. The weak symbol
4082 can be overridden at final link time by a non weak symbol. We can
4083 relax externally visible symbol because there is no shared library
4084 and such symbol can't be overridden (unless they are weak). */
d8273f3b 4085static int
ca43c854 4086relaxable_symbol (symbolS *symbol)
d8273f3b 4087{
dbb8ad49 4088 return ! S_IS_WEAK (symbol);
d8273f3b
SC
4089}
4090
60bcf0fa
NC
4091/* Force truly undefined symbols to their maximum size, and generally set up
4092 the frag list to be relaxed. */
4093int
ca43c854 4094md_estimate_size_before_relax (fragS *fragP, asection *segment)
60bcf0fa 4095{
606ab118
AM
4096 if (RELAX_LENGTH (fragP->fr_subtype) == STATE_UNDF)
4097 {
4098 if (S_GET_SEGMENT (fragP->fr_symbol) != segment
577300ce
SC
4099 || !relaxable_symbol (fragP->fr_symbol)
4100 || (segment != absolute_section
4101 && RELAX_STATE (fragP->fr_subtype) == STATE_INDEXED_OFFSET))
606ab118
AM
4102 {
4103 /* Non-relaxable cases. */
4104 int old_fr_fix;
4105 char *buffer_address;
60bcf0fa 4106
606ab118
AM
4107 old_fr_fix = fragP->fr_fix;
4108 buffer_address = fragP->fr_fix + fragP->fr_literal;
60bcf0fa 4109
606ab118
AM
4110 switch (RELAX_STATE (fragP->fr_subtype))
4111 {
4112 case STATE_PC_RELATIVE:
4113
4114 /* This relax is only for bsr and bra. */
9c2799c2 4115 gas_assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
606ab118
AM
4116 || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
4117 || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
4118
1370e33d 4119 if (flag_fixed_branches)
606ab118
AM
4120 as_bad_where (fragP->fr_file, fragP->fr_line,
4121 _("bra or bsr with undefined symbol."));
4122
4123 /* The symbol is undefined or in a separate section.
4124 Turn bra into a jmp and bsr into a jsr. The insn
4125 becomes 3 bytes long (instead of 2). A fixup is
4126 necessary for the unresolved symbol address. */
4127 fragP->fr_opcode[0] = convert_branch (fragP->fr_opcode[0]);
4128
13283e2d 4129 fix_new (fragP, fragP->fr_fix - 1, 2, fragP->fr_symbol,
606ab118 4130 fragP->fr_offset, 0, BFD_RELOC_16);
13283e2d 4131 fragP->fr_fix++;
606ab118 4132 break;
60bcf0fa 4133
606ab118 4134 case STATE_CONDITIONAL_BRANCH:
9c2799c2 4135 gas_assert (current_architecture & cpu6811);
60bcf0fa 4136
606ab118
AM
4137 fragP->fr_opcode[0] ^= 1; /* Reverse sense of branch. */
4138 fragP->fr_opcode[1] = 3; /* Skip next jmp insn (3 bytes). */
60bcf0fa 4139
606ab118
AM
4140 /* Don't use fr_opcode[2] because this may be
4141 in a different frag. */
4142 buffer_address[0] = M6811_JMP;
60bcf0fa 4143
606ab118
AM
4144 fragP->fr_fix++;
4145 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
4146 fragP->fr_offset, 0, BFD_RELOC_16);
4147 fragP->fr_fix += 2;
4148 break;
60bcf0fa 4149
606ab118 4150 case STATE_INDEXED_OFFSET:
9c2799c2 4151 gas_assert (current_architecture & cpu6812);
60bcf0fa 4152
c9e03e8b
SC
4153 if (fragP->fr_symbol
4154 && S_GET_SEGMENT (fragP->fr_symbol) == absolute_section)
4155 {
4156 fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_OFFSET,
4157 STATE_BITS5);
4158 /* Return the size of the variable part of the frag. */
4159 return md_relax_table[fragP->fr_subtype].rlx_length;
4160 }
4161 else
4162 {
4163 /* Switch the indexed operation to 16-bit mode. */
4164 fragP->fr_opcode[0] = fragP->fr_opcode[0] << 3;
4165 fragP->fr_opcode[0] |= 0xe2;
4166 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
4167 fragP->fr_offset, 0, BFD_RELOC_16);
4168 fragP->fr_fix += 2;
4169 }
606ab118 4170 break;
60bcf0fa 4171
75538612 4172 case STATE_INDEXED_PCREL:
9c2799c2 4173 gas_assert (current_architecture & cpu6812);
75538612
SC
4174
4175 if (fragP->fr_symbol
4176 && S_GET_SEGMENT (fragP->fr_symbol) == absolute_section)
4177 {
4178 fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_PCREL,
4179 STATE_BITS5);
4180 /* Return the size of the variable part of the frag. */
4181 return md_relax_table[fragP->fr_subtype].rlx_length;
4182 }
4183 else
4184 {
75538612
SC
4185 fragP->fr_opcode[0] = fragP->fr_opcode[0] << 3;
4186 fragP->fr_opcode[0] |= 0xe2;
87975d2a
AM
4187 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
4188 fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
75538612
SC
4189 fragP->fr_fix += 2;
4190 }
4191 break;
4192
606ab118 4193 case STATE_XBCC_BRANCH:
9c2799c2 4194 gas_assert (current_architecture & cpu6812);
606ab118
AM
4195
4196 fragP->fr_opcode[0] ^= 0x20; /* Reverse sense of branch. */
4197 fragP->fr_opcode[1] = 3; /* Skip next jmp insn (3 bytes). */
60bcf0fa 4198
606ab118
AM
4199 /* Don't use fr_opcode[2] because this may be
4200 in a different frag. */
4201 buffer_address[0] = M6812_JMP;
4202
4203 fragP->fr_fix++;
4204 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
4205 fragP->fr_offset, 0, BFD_RELOC_16);
4206 fragP->fr_fix += 2;
4207 break;
60bcf0fa 4208
606ab118 4209 case STATE_CONDITIONAL_BRANCH_6812:
9c2799c2 4210 gas_assert (current_architecture & cpu6812);
606ab118
AM
4211
4212 /* Translate into a lbcc branch. */
4213 fragP->fr_opcode[1] = fragP->fr_opcode[0];
4214 fragP->fr_opcode[0] = M6811_OPCODE_PAGE2;
4215
4216 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
e371935f 4217 fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
606ab118
AM
4218 fragP->fr_fix += 2;
4219 break;
4220
4221 default:
4222 as_fatal (_("Subtype %d is not recognized."), fragP->fr_subtype);
4223 }
60bcf0fa 4224 frag_wane (fragP);
60bcf0fa 4225
606ab118
AM
4226 /* Return the growth in the fixed part of the frag. */
4227 return fragP->fr_fix - old_fr_fix;
4228 }
60bcf0fa 4229
606ab118
AM
4230 /* Relaxable cases. */
4231 switch (RELAX_STATE (fragP->fr_subtype))
60bcf0fa 4232 {
606ab118
AM
4233 case STATE_PC_RELATIVE:
4234 /* This relax is only for bsr and bra. */
9c2799c2 4235 gas_assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
606ab118
AM
4236 || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
4237 || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
4238
4239 fragP->fr_subtype = ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE);
4240 break;
4241
4242 case STATE_CONDITIONAL_BRANCH:
9c2799c2 4243 gas_assert (current_architecture & cpu6811);
606ab118
AM
4244
4245 fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH,
4246 STATE_BYTE);
4247 break;
4248
4249 case STATE_INDEXED_OFFSET:
9c2799c2 4250 gas_assert (current_architecture & cpu6812);
606ab118 4251
60bcf0fa
NC
4252 fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_OFFSET,
4253 STATE_BITS5);
606ab118 4254 break;
60bcf0fa 4255
75538612 4256 case STATE_INDEXED_PCREL:
9c2799c2 4257 gas_assert (current_architecture & cpu6812);
75538612
SC
4258
4259 fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_PCREL,
4260 STATE_BITS5);
4261 break;
4262
606ab118 4263 case STATE_XBCC_BRANCH:
9c2799c2 4264 gas_assert (current_architecture & cpu6812);
60bcf0fa 4265
60bcf0fa 4266 fragP->fr_subtype = ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_BYTE);
606ab118 4267 break;
60bcf0fa 4268
606ab118 4269 case STATE_CONDITIONAL_BRANCH_6812:
9c2799c2 4270 gas_assert (current_architecture & cpu6812);
60bcf0fa 4271
60bcf0fa
NC
4272 fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812,
4273 STATE_BYTE);
606ab118 4274 break;
60bcf0fa 4275 }
60bcf0fa
NC
4276 }
4277
606ab118
AM
4278 if (fragP->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))
4279 as_fatal (_("Subtype %d is not recognized."), fragP->fr_subtype);
4280
4281 /* Return the size of the variable part of the frag. */
4282 return md_relax_table[fragP->fr_subtype].rlx_length;
60bcf0fa
NC
4283}
4284
e371935f
SC
4285/* See whether we need to force a relocation into the output file. */
4286int
ca43c854 4287tc_m68hc11_force_relocation (fixS *fixP)
e371935f 4288{
ae6063d4
AM
4289 if (fixP->fx_r_type == BFD_RELOC_M68HC11_RL_GROUP)
4290 return 1;
a161fe53 4291
ae6063d4 4292 return generic_force_reloc (fixP);
e371935f
SC
4293}
4294
4295/* Here we decide which fixups can be adjusted to make them relative
4296 to the beginning of the section instead of the symbol. Basically
4297 we need to make sure that the linker relaxation is done
4298 correctly, so in some cases we force the original symbol to be
4299 used. */
4300int
ca43c854 4301tc_m68hc11_fix_adjustable (fixS *fixP)
e371935f 4302{
e371935f
SC
4303 switch (fixP->fx_r_type)
4304 {
4305 /* For the linker relaxation to work correctly, these relocs
4306 need to be on the symbol itself. */
4307 case BFD_RELOC_16:
e371935f
SC
4308 case BFD_RELOC_M68HC11_RL_JUMP:
4309 case BFD_RELOC_M68HC11_RL_GROUP:
4310 case BFD_RELOC_VTABLE_INHERIT:
4311 case BFD_RELOC_VTABLE_ENTRY:
577300ce 4312 case BFD_RELOC_32:
2d94a61a
SC
4313
4314 /* The memory bank addressing translation also needs the original
4315 symbol. */
577300ce 4316 case BFD_RELOC_M68HC11_LO16:
2d94a61a
SC
4317 case BFD_RELOC_M68HC11_PAGE:
4318 case BFD_RELOC_M68HC11_24:
e371935f
SC
4319 return 0;
4320
e371935f
SC
4321 default:
4322 return 1;
4323 }
4324}
4325
94f592af 4326void
55cf6793 4327md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
60bcf0fa
NC
4328{
4329 char *where;
94f592af 4330 long value = * valP;
60bcf0fa 4331
94f592af
NC
4332 if (fixP->fx_addsy == (symbolS *) NULL)
4333 fixP->fx_done = 1;
4334
a161fe53
AM
4335 /* We don't actually support subtracting a symbol. */
4336 if (fixP->fx_subsy != (symbolS *) NULL)
4bf09429 4337 as_bad_subtract (fixP);
60bcf0fa 4338
60bcf0fa
NC
4339 /* Patch the instruction with the resolved operand. Elf relocation
4340 info will also be generated to take care of linker/loader fixups.
4341 The 68HC11 addresses only 64Kb, we are only concerned by 8 and 16-bit
4342 relocs. BFD_RELOC_8 is basically used for .page0 access (the linker
4343 will warn for overflows). BFD_RELOC_8_PCREL should not be generated
4344 because it's either resolved or turned out into non-relative insns (see
4345 relax table, bcc, bra, bsr transformations)
4346
4347 The BFD_RELOC_32 is necessary for the support of --gstabs. */
94f592af 4348 where = fixP->fx_frag->fr_literal + fixP->fx_where;
60bcf0fa 4349
94f592af 4350 switch (fixP->fx_r_type)
60bcf0fa
NC
4351 {
4352 case BFD_RELOC_32:
4353 bfd_putb32 ((bfd_vma) value, (unsigned char *) where);
4354 break;
4355
7bfda7eb
SC
4356 case BFD_RELOC_24:
4357 case BFD_RELOC_M68HC11_24:
4358 bfd_putb16 ((bfd_vma) (value & 0x0ffff), (unsigned char *) where);
4359 ((bfd_byte*) where)[2] = ((value >> 16) & 0x0ff);
4360 break;
4361
60bcf0fa
NC
4362 case BFD_RELOC_16:
4363 case BFD_RELOC_16_PCREL:
7bfda7eb 4364 case BFD_RELOC_M68HC11_LO16:
60bcf0fa
NC
4365 bfd_putb16 ((bfd_vma) value, (unsigned char *) where);
4366 if (value < -65537 || value > 65535)
94f592af 4367 as_bad_where (fixP->fx_file, fixP->fx_line,
60bcf0fa
NC
4368 _("Value out of 16-bit range."));
4369 break;
4370
4371 case BFD_RELOC_M68HC11_HI8:
6927f982
NC
4372 /* Caution, %hi(<symbol>+%ld) will generate incorrect code if %lo
4373 causes a carry. */
4374 case BFD_RELOC_M68HC12_HI8XG:
60bcf0fa 4375 value = value >> 8;
fafb6d17 4376 /* Fall through. */
60bcf0fa 4377
6927f982 4378 case BFD_RELOC_M68HC12_LO8XG:
60bcf0fa
NC
4379 case BFD_RELOC_M68HC11_LO8:
4380 case BFD_RELOC_8:
7bfda7eb 4381 case BFD_RELOC_M68HC11_PAGE:
60bcf0fa
NC
4382 ((bfd_byte *) where)[0] = (bfd_byte) value;
4383 break;
4384
4385 case BFD_RELOC_8_PCREL:
60bcf0fa
NC
4386 ((bfd_byte *) where)[0] = (bfd_byte) value;
4387
4388 if (value < -128 || value > 127)
94f592af 4389 as_bad_where (fixP->fx_file, fixP->fx_line,
60bcf0fa
NC
4390 _("Value %ld too large for 8-bit PC-relative branch."),
4391 value);
4392 break;
4393
6927f982
NC
4394 /* These next two are for XGATE. */
4395 case BFD_RELOC_M68HC12_9_PCREL:
4396 ((bfd_byte *) where)[0] |= (bfd_byte) ((value >>9) & 0x01);
4397 ((bfd_byte *) where)[1] = (bfd_byte) ((value>>1) & 0xff);
4398 if (value < -512 || value > 511)
4399 as_bad_where (fixP->fx_file, fixP->fx_line,
4400 _("Value %ld too large for 9-bit PC-relative branch."),
4401 value);
4402 break;
4403
4404 case BFD_RELOC_M68HC12_10_PCREL:
4405 ((bfd_byte *) where)[0] |= (bfd_byte) ((value >>9) & 0x03);
4406 ((bfd_byte *) where)[1] = (bfd_byte) ((value>>1) & 0xff);
4407 if (value < -1024 || value > 1023)
4408 as_bad_where (fixP->fx_file, fixP->fx_line,
4409 _("Value %ld too large for 10-bit PC-relative branch."),
4410 value);
4411
4412 break;
4413
60bcf0fa
NC
4414 case BFD_RELOC_M68HC11_3B:
4415 if (value <= 0 || value > 8)
94f592af 4416 as_bad_where (fixP->fx_file, fixP->fx_line,
60bcf0fa
NC
4417 _("Auto increment/decrement offset '%ld' is out of range."),
4418 value);
4419 if (where[0] & 0x8)
4420 value = 8 - value;
4421 else
4422 value--;
4423
4424 where[0] = where[0] | (value & 0x07);
4425 break;
4426
28d39d1a
NC
4427 case BFD_RELOC_M68HC12_5B:
4428 if (value < -16 || value > 15)
4429 as_bad_where (fixP->fx_file, fixP->fx_line,
4430 _("Offset out of 5-bit range for movw/movb insn: %ld"),
4431 value);
4432 if (value >= 0)
4433 where[0] |= value;
3739860c 4434 else
28d39d1a
NC
4435 where[0] |= (0x10 | (16 + value));
4436 break;
4437
6927f982
NC
4438 case BFD_RELOC_M68HC12_9B:
4439 if (value < -256 || value > 255)
4440 as_bad_where (fixP->fx_file, fixP->fx_line,
4441 _("Offset out of 9-bit range for movw/movb insn: %ld"),
4442 value);
4443 /* sign bit already in xb postbyte */
4444 if (value >= 0)
4445 where[1] = value;
3739860c 4446 else
6927f982
NC
4447 where[1] = (256 + value);
4448 break;
4449
4450 case BFD_RELOC_M68HC12_16B:
4451 if (value < -32768 || value > 32767)
4452 as_bad_where (fixP->fx_file, fixP->fx_line,
4453 _("Offset out of 16-bit range for movw/movb insn: %ld"),
4454 value);
4455 if (value < 0)
4456 value += 65536;
4457
fcdc4d0c
SK
4458 where[0] = (value >> 8);
4459 where[1] = (value & 0xff);
6927f982
NC
4460 break;
4461
e371935f
SC
4462 case BFD_RELOC_M68HC11_RL_JUMP:
4463 case BFD_RELOC_M68HC11_RL_GROUP:
4464 case BFD_RELOC_VTABLE_INHERIT:
4465 case BFD_RELOC_VTABLE_ENTRY:
4466 fixP->fx_done = 0;
4467 return;
4468
60bcf0fa
NC
4469 default:
4470 as_fatal (_("Line %d: unknown relocation type: 0x%x."),
94f592af 4471 fixP->fx_line, fixP->fx_r_type);
60bcf0fa 4472 }
60bcf0fa 4473}
eb086b59
SC
4474
4475/* Set the ELF specific flags. */
4476void
ca43c854 4477m68hc11_elf_final_processing (void)
eb086b59 4478{
d01030e6
SC
4479 if (current_architecture & cpu6812s)
4480 elf_flags |= EF_M68HCS12_MACH;
eb086b59
SC
4481 elf_elfheader (stdoutput)->e_flags &= ~EF_M68HC11_ABI;
4482 elf_elfheader (stdoutput)->e_flags |= elf_flags;
4483}
bdfd67fa
SK
4484
4485/* Process directives specified via pseudo ops */
4486static void
4487s_m68hc11_parse_pseudo_instruction (int pseudo_insn)
4488{
4489 switch (pseudo_insn)
4490 {
4491 case E_M68HC11_NO_BANK_WARNING:
4492 elf_flags |= E_M68HC11_NO_BANK_WARNING;
4493 break;
4494 default:
4495 as_bad (_("Invalid directive"));
4496 }
4497}