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