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