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