* tc-m68hc11.c (s_m68hc11_parse_pseudo_instruction):
[deliverable/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 {
1606 fixS *fixp;
1607
1608 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
b34976b6 1609 oper, TRUE, BFD_RELOC_8_PCREL);
60bcf0fa
NC
1610 fixp->fx_pcrel_adjust = 1;
1611 }
1612 else
1613 {
577300ce
SC
1614 fixS *fixp;
1615 int reloc;
1616
1617 /* Now create an 8-bit fixup. If there was some %hi, %lo
1618 or %page modifier, generate the reloc accordingly. */
1619 if (opmode & M6811_OP_HIGH_ADDR)
1620 reloc = BFD_RELOC_M68HC11_HI8;
1621 else if (opmode & M6811_OP_LOW_ADDR)
1622 reloc = BFD_RELOC_M68HC11_LO8;
1623 else if (opmode & M6811_OP_PAGE_ADDR)
1624 reloc = BFD_RELOC_M68HC11_PAGE;
1625 else
1626 reloc = BFD_RELOC_8;
1627
1628 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
1629 oper, FALSE, reloc);
1630 if (reloc != BFD_RELOC_8)
1631 fixp->fx_no_overflow = 1;
60bcf0fa
NC
1632 }
1633 number_to_chars_bigendian (f, 0, 1);
1634 }
1635 else
1636 {
1637 as_fatal (_("Operand `%x' not recognized in fixup8."), oper->X_op);
1638 }
1639}
1640
986c6f4b 1641/* Put a 2 byte expression described by 'oper'. If this expression contains
60bcf0fa
NC
1642 unresolved symbols, generate a 16-bit fixup. */
1643static void
ca43c854 1644fixup16 (expressionS *oper, int mode, int opmode ATTRIBUTE_UNUSED)
60bcf0fa
NC
1645{
1646 char *f;
1647
1648 f = frag_more (2);
1649
1650 if (oper->X_op == O_constant)
1651 {
1652 if (!check_range (oper->X_add_number, mode))
1653 {
1654 as_bad (_("Operand out of 16-bit range: `%ld'."),
fafb6d17 1655 oper->X_add_number);
60bcf0fa
NC
1656 }
1657 number_to_chars_bigendian (f, oper->X_add_number & 0x0FFFF, 2);
1658 }
1659 else if (oper->X_op != O_register)
1660 {
1661 fixS *fixp;
577300ce
SC
1662 int reloc;
1663
1664 if ((opmode & M6811_OP_CALL_ADDR) && (mode & M6811_OP_IMM16))
1665 reloc = BFD_RELOC_M68HC11_LO16;
1666 else if (mode & M6812_OP_JUMP_REL16)
1667 reloc = BFD_RELOC_16_PCREL;
1668 else if (mode & M6812_OP_PAGE)
1669 reloc = BFD_RELOC_M68HC11_LO16;
1670 else
1671 reloc = BFD_RELOC_16;
60bcf0fa
NC
1672
1673 /* Now create a 16-bit fixup. */
1674 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 2,
1675 oper,
577300ce
SC
1676 reloc == BFD_RELOC_16_PCREL,
1677 reloc);
60bcf0fa 1678 number_to_chars_bigendian (f, 0, 2);
577300ce 1679 if (reloc == BFD_RELOC_16_PCREL)
60bcf0fa 1680 fixp->fx_pcrel_adjust = 2;
577300ce
SC
1681 if (reloc == BFD_RELOC_M68HC11_LO16)
1682 fixp->fx_no_overflow = 1;
60bcf0fa
NC
1683 }
1684 else
1685 {
1686 as_fatal (_("Operand `%x' not recognized in fixup16."), oper->X_op);
1687 }
1688}
7bfda7eb
SC
1689
1690/* Put a 3 byte expression described by 'oper'. If this expression contains
1691 unresolved symbols, generate a 24-bit fixup. */
1692static void
ca43c854 1693fixup24 (expressionS *oper, int mode, int opmode ATTRIBUTE_UNUSED)
7bfda7eb
SC
1694{
1695 char *f;
1696
1697 f = frag_more (3);
1698
1699 if (oper->X_op == O_constant)
1700 {
1701 if (!check_range (oper->X_add_number, mode))
1702 {
1703 as_bad (_("Operand out of 16-bit range: `%ld'."),
1704 oper->X_add_number);
1705 }
1706 number_to_chars_bigendian (f, oper->X_add_number & 0x0FFFFFF, 3);
1707 }
1708 else if (oper->X_op != O_register)
1709 {
7bfda7eb 1710 /* Now create a 24-bit fixup. */
87975d2a
AM
1711 fix_new_exp (frag_now, f - frag_now->fr_literal, 3,
1712 oper, FALSE, BFD_RELOC_M68HC11_24);
7bfda7eb
SC
1713 number_to_chars_bigendian (f, 0, 3);
1714 }
1715 else
1716 {
1717 as_fatal (_("Operand `%x' not recognized in fixup16."), oper->X_op);
1718 }
1719}
6927f982
NC
1720
1721/* XGATE Put a 1 byte expression described by 'oper'. If this expression
1722 containts unresolved symbols, generate an 8-bit fixup. */
1723static void
1724fixup8_xg (expressionS *oper, int mode, int opmode)
1725{
1726 char *f;
1727
1728 f = frag_more (1);
1729
1730 if (oper->X_op == O_constant)
1731 {
1732 fixS *fixp;
1733 int reloc;
1734
1735 if ((opmode & M6811_OP_HIGH_ADDR) || (opmode & M6811_OP_LOW_ADDR))
1736 {
1737 if (opmode & M6811_OP_HIGH_ADDR)
1738 reloc = BFD_RELOC_M68HC11_HI8;
1739 else
1740 reloc = BFD_RELOC_M68HC11_LO8;
1741
1742 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
1743 oper, FALSE, reloc);
1744 fixp->fx_no_overflow = 1;
1745 number_to_chars_bigendian (f, 0, 1);
1746 }
1747 else
1748 {
1749 if (!(check_range (oper->X_add_number, mode)))
1750 as_bad (_("Operand out of 8-bit range: `%ld'."),
1751 oper->X_add_number);
1752 number_to_chars_bigendian (f, oper->X_add_number & 0x0FF, 1);
1753 }
1754 }
1755 else if (oper->X_op != O_register)
1756 {
1757 if (mode == M68XG_OP_REL9)
1758 {
1759 fixS *fixp;
1760
1761 /* Future improvement:
1762 This fixup/reloc isn't adding on constants to symbols. */
1763 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal -1, 2,
1764 oper, TRUE, BFD_RELOC_M68HC12_9_PCREL);
1765 fixp->fx_pcrel_adjust = 1;
1766 }
1767 else if (mode == M68XG_OP_REL10)
1768 {
1769 fixS *fixp;
1770
1771 /* Future improvement:
1772 This fixup/reloc isn't adding on constants to symbols. */
1773 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal -1, 2,
1774 oper, TRUE, BFD_RELOC_M68HC12_10_PCREL);
1775 fixp->fx_pcrel_adjust = 1;
1776 }
1777 else
1778 {
1779 fixS *fixp;
1780 int reloc;
1781
1782 /* Now create an 8-bit fixup. If there was some %hi, %lo
1783 modifier, generate the reloc accordingly. */
1784 if (opmode & M6811_OP_HIGH_ADDR)
1785 reloc = BFD_RELOC_M68HC11_HI8;
1786 else if (opmode & M6811_OP_LOW_ADDR)
1787 reloc = BFD_RELOC_M68HC11_LO8;
1788 else
1789 reloc = BFD_RELOC_8;
1790
1791 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
1792 oper, FALSE, reloc);
1793 if (reloc != BFD_RELOC_8)
1794 fixp->fx_no_overflow = 1;
1795 }
1796 number_to_chars_bigendian (f, 0, 1);
1797 }
1798 else
1799 as_fatal (_("Operand `%x' not recognized in fixup8."), oper->X_op);
1800}
60bcf0fa
NC
1801\f
1802/* 68HC11 and 68HC12 code generation. */
1803
1804/* Translate the short branch/bsr instruction into a long branch. */
6927f982 1805
60bcf0fa 1806static unsigned char
ca43c854 1807convert_branch (unsigned char code)
60bcf0fa
NC
1808{
1809 if (IS_OPCODE (code, M6812_BSR))
1810 return M6812_JSR;
1811 else if (IS_OPCODE (code, M6811_BSR))
1812 return M6811_JSR;
1813 else if (IS_OPCODE (code, M6811_BRA))
1814 return (current_architecture & cpu6812) ? M6812_JMP : M6811_JMP;
1815 else
1816 as_fatal (_("Unexpected branch conversion with `%x'"), code);
1817
1818 /* Keep gcc happy. */
1819 return M6811_JSR;
1820}
1821
1822/* Start a new insn that contains at least 'size' bytes. Record the
1823 line information of that insn in the dwarf2 debug sections. */
fafb6d17 1824static char *
ca43c854 1825m68hc11_new_insn (int size)
60bcf0fa 1826{
fafb6d17 1827 char *f;
60bcf0fa
NC
1828
1829 f = frag_more (size);
1830
4dc7ead9 1831 dwarf2_emit_insn (size);
fafb6d17 1832
60bcf0fa
NC
1833 return f;
1834}
1835
1836/* Builds a jump instruction (bra, bcc, bsr). */
1837static void
ca43c854
SC
1838build_jump_insn (struct m68hc11_opcode *opcode, operand operands[],
1839 int nb_operands, int jmp_mode)
60bcf0fa
NC
1840{
1841 unsigned char code;
60bcf0fa
NC
1842 char *f;
1843 unsigned long n;
1844
67c1ffbe 1845 /* The relative branch conversion is not supported for
60bcf0fa 1846 brclr and brset. */
9c2799c2
NC
1847 gas_assert ((opcode->format & M6811_OP_BITMASK) == 0);
1848 gas_assert (nb_operands == 1);
1849 gas_assert (operands[0].reg1 == REG_NONE && operands[0].reg2 == REG_NONE);
60bcf0fa
NC
1850
1851 code = opcode->opcode;
60bcf0fa
NC
1852
1853 n = operands[0].exp.X_add_number;
1854
1855 /* Turn into a long branch:
1856 - when force long branch option (and not for jbcc pseudos),
1857 - when jbcc and the constant is out of -128..127 range,
1858 - when branch optimization is allowed and branch out of range. */
1859 if ((jmp_mode == 0 && flag_force_long_jumps)
1860 || (operands[0].exp.X_op == O_constant
1861 && (!check_range (n, opcode->format) &&
1370e33d 1862 (jmp_mode == 1 || flag_fixed_branches == 0))))
60bcf0fa 1863 {
fd99afa7 1864 fix_new (frag_now, frag_now_fix (), 0,
e371935f
SC
1865 &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
1866
60bcf0fa
NC
1867 if (code == M6811_BSR || code == M6811_BRA || code == M6812_BSR)
1868 {
1869 code = convert_branch (code);
1870
1871 f = m68hc11_new_insn (1);
1872 number_to_chars_bigendian (f, code, 1);
1873 }
1874 else if (current_architecture & cpu6812)
1875 {
1876 /* 68HC12: translate the bcc into a lbcc. */
1877 f = m68hc11_new_insn (2);
1878 number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1);
1879 number_to_chars_bigendian (f + 1, code, 1);
1880 fixup16 (&operands[0].exp, M6812_OP_JUMP_REL16,
1881 M6812_OP_JUMP_REL16);
1882 return;
1883 }
1884 else
1885 {
1886 /* 68HC11: translate the bcc into b!cc +3; jmp <L>. */
1887 f = m68hc11_new_insn (3);
1888 code ^= 1;
1889 number_to_chars_bigendian (f, code, 1);
1890 number_to_chars_bigendian (f + 1, 3, 1);
1891 number_to_chars_bigendian (f + 2, M6811_JMP, 1);
1892 }
1893 fixup16 (&operands[0].exp, M6811_OP_IND16, M6811_OP_IND16);
1894 return;
1895 }
1896
1897 /* Branch with a constant that must fit in 8-bits. */
1898 if (operands[0].exp.X_op == O_constant)
1899 {
1900 if (!check_range (n, opcode->format))
1901 {
1902 as_bad (_("Operand out of range for a relative branch: `%ld'"),
1903 n);
1904 }
1905 else if (opcode->format & M6812_OP_JUMP_REL16)
1906 {
1907 f = m68hc11_new_insn (4);
1908 number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1);
1909 number_to_chars_bigendian (f + 1, code, 1);
1910 number_to_chars_bigendian (f + 2, n & 0x0ffff, 2);
1911 }
1912 else
1913 {
1914 f = m68hc11_new_insn (2);
1915 number_to_chars_bigendian (f, code, 1);
1916 number_to_chars_bigendian (f + 1, n & 0x0FF, 1);
1917 }
1918 }
1919 else if (opcode->format & M6812_OP_JUMP_REL16)
1920 {
fd99afa7 1921 fix_new (frag_now, frag_now_fix (), 0,
e371935f
SC
1922 &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
1923
60bcf0fa
NC
1924 f = m68hc11_new_insn (2);
1925 number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1);
1926 number_to_chars_bigendian (f + 1, code, 1);
1927 fixup16 (&operands[0].exp, M6812_OP_JUMP_REL16, M6812_OP_JUMP_REL16);
1928 }
1929 else
1930 {
91d6fa6a 1931 char *op;
60bcf0fa 1932
fd99afa7 1933 fix_new (frag_now, frag_now_fix (), 0,
e371935f
SC
1934 &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
1935
60bcf0fa 1936 /* Branch offset must fit in 8-bits, don't do some relax. */
1370e33d 1937 if (jmp_mode == 0 && flag_fixed_branches)
60bcf0fa 1938 {
91d6fa6a
NC
1939 op = m68hc11_new_insn (1);
1940 number_to_chars_bigendian (op, code, 1);
60bcf0fa
NC
1941 fixup8 (&operands[0].exp, M6811_OP_JUMP_REL, M6811_OP_JUMP_REL);
1942 }
1943
1944 /* bra/bsr made be changed into jmp/jsr. */
1945 else if (code == M6811_BSR || code == M6811_BRA || code == M6812_BSR)
1946 {
4fe7ef96 1947 /* Allocate worst case storage. */
91d6fa6a
NC
1948 op = m68hc11_new_insn (3);
1949 number_to_chars_bigendian (op, code, 1);
1950 number_to_chars_bigendian (op + 1, 0, 1);
4fe7ef96
SC
1951 frag_variant (rs_machine_dependent, 1, 1,
1952 ENCODE_RELAX (STATE_PC_RELATIVE, STATE_UNDF),
1953 operands[0].exp.X_add_symbol, (offsetT) n,
91d6fa6a 1954 op);
60bcf0fa
NC
1955 }
1956 else if (current_architecture & cpu6812)
1957 {
91d6fa6a
NC
1958 op = m68hc11_new_insn (2);
1959 number_to_chars_bigendian (op, code, 1);
1960 number_to_chars_bigendian (op + 1, 0, 1);
60bcf0fa
NC
1961 frag_var (rs_machine_dependent, 2, 2,
1962 ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_UNDF),
91d6fa6a 1963 operands[0].exp.X_add_symbol, (offsetT) n, op);
60bcf0fa
NC
1964 }
1965 else
1966 {
91d6fa6a
NC
1967 op = m68hc11_new_insn (2);
1968 number_to_chars_bigendian (op, code, 1);
1969 number_to_chars_bigendian (op + 1, 0, 1);
60bcf0fa
NC
1970 frag_var (rs_machine_dependent, 3, 3,
1971 ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_UNDF),
91d6fa6a 1972 operands[0].exp.X_add_symbol, (offsetT) n, op);
60bcf0fa
NC
1973 }
1974 }
1975}
1976
1977/* Builds a dbne/dbeq/tbne/tbeq instruction. */
1978static void
ca43c854
SC
1979build_dbranch_insn (struct m68hc11_opcode *opcode, operand operands[],
1980 int nb_operands, int jmp_mode)
60bcf0fa
NC
1981{
1982 unsigned char code;
60bcf0fa
NC
1983 char *f;
1984 unsigned long n;
1985
67c1ffbe 1986 /* The relative branch conversion is not supported for
60bcf0fa 1987 brclr and brset. */
9c2799c2
NC
1988 gas_assert ((opcode->format & M6811_OP_BITMASK) == 0);
1989 gas_assert (nb_operands == 2);
1990 gas_assert (operands[0].reg1 != REG_NONE);
60bcf0fa
NC
1991
1992 code = opcode->opcode & 0x0FF;
60bcf0fa
NC
1993
1994 f = m68hc11_new_insn (1);
1995 number_to_chars_bigendian (f, code, 1);
1996
1997 n = operands[1].exp.X_add_number;
1998 code = operands[0].reg1;
1999
2000 if (operands[0].reg1 == REG_NONE || operands[0].reg1 == REG_CCR
2001 || operands[0].reg1 == REG_PC)
2002 as_bad (_("Invalid register for dbcc/tbcc instruction."));
2003
2004 if (opcode->format & M6812_OP_IBCC_MARKER)
2005 code |= 0x80;
2006 else if (opcode->format & M6812_OP_TBCC_MARKER)
2007 code |= 0x40;
2008
2009 if (!(opcode->format & M6812_OP_EQ_MARKER))
2010 code |= 0x20;
2011
2012 /* Turn into a long branch:
2013 - when force long branch option (and not for jbcc pseudos),
2014 - when jdbcc and the constant is out of -256..255 range,
2015 - when branch optimization is allowed and branch out of range. */
2016 if ((jmp_mode == 0 && flag_force_long_jumps)
2017 || (operands[1].exp.X_op == O_constant
2018 && (!check_range (n, M6812_OP_IBCC_MARKER) &&
1370e33d 2019 (jmp_mode == 1 || flag_fixed_branches == 0))))
60bcf0fa
NC
2020 {
2021 f = frag_more (2);
2022 code ^= 0x20;
2023 number_to_chars_bigendian (f, code, 1);
2024 number_to_chars_bigendian (f + 1, M6812_JMP, 1);
2025 fixup16 (&operands[0].exp, M6811_OP_IND16, M6811_OP_IND16);
2026 return;
2027 }
2028
2029 /* Branch with a constant that must fit in 9-bits. */
2030 if (operands[1].exp.X_op == O_constant)
2031 {
2032 if (!check_range (n, M6812_OP_IBCC_MARKER))
2033 {
2034 as_bad (_("Operand out of range for a relative branch: `%ld'"),
2035 n);
2036 }
2037 else
2038 {
2039 if ((long) n < 0)
2040 code |= 0x10;
2041
2042 f = frag_more (2);
2043 number_to_chars_bigendian (f, code, 1);
2044 number_to_chars_bigendian (f + 1, n & 0x0FF, 1);
2045 }
2046 }
2047 else
2048 {
2049 /* Branch offset must fit in 8-bits, don't do some relax. */
1370e33d 2050 if (jmp_mode == 0 && flag_fixed_branches)
60bcf0fa
NC
2051 {
2052 fixup8 (&operands[0].exp, M6811_OP_JUMP_REL, M6811_OP_JUMP_REL);
2053 }
2054
2055 else
2056 {
2057 f = frag_more (2);
2058 number_to_chars_bigendian (f, code, 1);
2059 number_to_chars_bigendian (f + 1, 0, 1);
2060 frag_var (rs_machine_dependent, 3, 3,
2061 ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_UNDF),
2062 operands[1].exp.X_add_symbol, (offsetT) n, f);
2063 }
2064 }
2065}
2066
2067#define OP_EXTENDED (M6811_OP_PAGE2 | M6811_OP_PAGE3 | M6811_OP_PAGE4)
2068
2069/* Assemble the post index byte for 68HC12 extended addressing modes. */
6927f982 2070
60bcf0fa 2071static int
ca43c854 2072build_indexed_byte (operand *op, int format ATTRIBUTE_UNUSED, int move_insn)
60bcf0fa
NC
2073{
2074 unsigned char byte = 0;
2075 char *f;
2076 int mode;
2077 long val;
2078
2079 val = op->exp.X_add_number;
2080 mode = op->mode;
2081 if (mode & M6812_AUTO_INC_DEC)
2082 {
2083 byte = 0x20;
2084 if (mode & (M6812_POST_INC | M6812_POST_DEC))
2085 byte |= 0x10;
2086
2087 if (op->exp.X_op == O_constant)
2088 {
2089 if (!check_range (val, mode))
6927f982
NC
2090 as_bad (_("Increment/decrement value is out of range: `%ld'."),
2091 val);
2092
60bcf0fa
NC
2093 if (mode & (M6812_POST_INC | M6812_PRE_INC))
2094 byte |= (val - 1) & 0x07;
2095 else
2096 byte |= (8 - ((val) & 7)) | 0x8;
2097 }
6927f982 2098
60bcf0fa
NC
2099 switch (op->reg1)
2100 {
2101 case REG_NONE:
2102 as_fatal (_("Expecting a register."));
2103
2104 case REG_X:
2105 byte |= 0;
2106 break;
2107
2108 case REG_Y:
2109 byte |= 0x40;
2110 break;
2111
2112 case REG_SP:
2113 byte |= 0x80;
2114 break;
2115
2116 default:
2117 as_bad (_("Invalid register for post/pre increment."));
2118 break;
2119 }
2120
2121 f = frag_more (1);
2122 number_to_chars_bigendian (f, byte, 1);
2123 return 1;
2124 }
2125
7bfda7eb 2126 if (mode & (M6812_OP_IDX | M6812_OP_D_IDX_2))
60bcf0fa
NC
2127 {
2128 switch (op->reg1)
2129 {
2130 case REG_X:
2131 byte = 0;
2132 break;
2133
2134 case REG_Y:
2135 byte = 1;
2136 break;
2137
2138 case REG_SP:
2139 byte = 2;
2140 break;
2141
2142 case REG_PC:
2143 byte = 3;
2144 break;
2145
2146 default:
2147 as_bad (_("Invalid register."));
2148 break;
2149 }
6927f982 2150
60bcf0fa
NC
2151 if (op->exp.X_op == O_constant)
2152 {
2153 if (!check_range (val, M6812_OP_IDX))
6927f982 2154 as_bad (_("Offset out of 16-bit range: %ld."), val);
60bcf0fa 2155
6927f982
NC
2156 if (move_insn && !(val >= -16 && val <= 15)
2157 && ((!(mode & M6812_OP_IDX) && !(mode & M6812_OP_D_IDX_2))
2158 || !(current_architecture & cpu9s12x)))
60bcf0fa 2159 {
ae3e85dd 2160 as_bad (_("Offset out of 5-bit range for movw/movb insn: %ld."),
098f2ec3 2161 val);
60bcf0fa
NC
2162 return -1;
2163 }
2164
7bfda7eb 2165 if (val >= -16 && val <= 15 && !(mode & M6812_OP_D_IDX_2))
60bcf0fa
NC
2166 {
2167 byte = byte << 6;
2168 byte |= val & 0x1f;
2169 f = frag_more (1);
2170 number_to_chars_bigendian (f, byte, 1);
2171 return 1;
2172 }
7bfda7eb 2173 else if (val >= -256 && val <= 255 && !(mode & M6812_OP_D_IDX_2))
60bcf0fa
NC
2174 {
2175 byte = byte << 3;
2176 byte |= 0xe0;
2177 if (val < 0)
2178 byte |= 0x1;
2179 f = frag_more (2);
2180 number_to_chars_bigendian (f, byte, 1);
2181 number_to_chars_bigendian (f + 1, val & 0x0FF, 1);
2182 return 2;
2183 }
2184 else
2185 {
2186 byte = byte << 3;
7bfda7eb 2187 if (mode & M6812_OP_D_IDX_2)
60bcf0fa
NC
2188 byte |= 0xe3;
2189 else
2190 byte |= 0xe2;
2191
2192 f = frag_more (3);
2193 number_to_chars_bigendian (f, byte, 1);
2194 number_to_chars_bigendian (f + 1, val & 0x0FFFF, 2);
2195 return 3;
2196 }
2197 }
6927f982 2198
7bfda7eb
SC
2199 if (mode & M6812_OP_D_IDX_2)
2200 {
2201 byte = (byte << 3) | 0xe3;
2202 f = frag_more (1);
2203 number_to_chars_bigendian (f, byte, 1);
2204
2205 fixup16 (&op->exp, 0, 0);
2206 }
2207 else if (op->reg1 != REG_PC)
098f2ec3 2208 {
c9e03e8b
SC
2209 symbolS *sym;
2210 offsetT off;
2211
098f2ec3
KH
2212 f = frag_more (1);
2213 number_to_chars_bigendian (f, byte, 1);
c9e03e8b
SC
2214 sym = op->exp.X_add_symbol;
2215 off = op->exp.X_add_number;
2216 if (op->exp.X_op != O_symbol)
2217 {
2218 sym = make_expr_symbol (&op->exp);
2219 off = 0;
2220 }
6927f982 2221
28d39d1a
NC
2222 /* movb/movw cannot be relaxed. */
2223 if (move_insn)
2224 {
6927f982
NC
2225 if ((mode & M6812_OP_IDX) && (current_architecture & cpu9s12x))
2226 {
2227 /* Must treat as a 16bit relocate as size of final result is unknown. */
2228
2229 byte <<= 3;
6832c67c 2230 byte |= 0xe2;
6927f982
NC
2231 number_to_chars_bigendian (f, byte, 1);
2232 fix_new (frag_now, f - frag_now->fr_literal, 2,
2233 sym, off, 0, BFD_RELOC_M68HC12_16B);
2234 f = frag_more (2);
2235 return 1;
2236 }
2237 else
2238 {
2239 /* Non-S12X will fail at relocate stage if offset out of range. */
2240 byte <<= 6;
2241 number_to_chars_bigendian (f, byte, 1);
2242 fix_new (frag_now, f - frag_now->fr_literal, 1,
2243 sym, off, 0, BFD_RELOC_M68HC12_5B);
2244 return 1;
2245 }
28d39d1a
NC
2246 }
2247 else
2248 {
2249 number_to_chars_bigendian (f, byte, 1);
2250 frag_var (rs_machine_dependent, 2, 2,
2251 ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_UNDF),
2252 sym, off, f);
2253 }
098f2ec3 2254 }
88051039 2255 else
098f2ec3
KH
2256 {
2257 f = frag_more (1);
6927f982 2258
28d39d1a
NC
2259 /* movb/movw cannot be relaxed. */
2260 if (move_insn)
2261 {
2262 byte <<= 6;
2263 number_to_chars_bigendian (f, byte, 1);
2264 fix_new (frag_now, f - frag_now->fr_literal, 1,
2265 op->exp.X_add_symbol, op->exp.X_add_number, 0, BFD_RELOC_M68HC12_5B);
2266 return 1;
2267 }
2268 else
2269 {
2270 number_to_chars_bigendian (f, byte, 1);
2271 frag_var (rs_machine_dependent, 2, 2,
2272 ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_UNDF),
2273 op->exp.X_add_symbol,
2274 op->exp.X_add_number, f);
2275 }
098f2ec3 2276 }
60bcf0fa
NC
2277 return 3;
2278 }
2279
7bfda7eb 2280 if (mode & (M6812_OP_REG | M6812_OP_D_IDX))
60bcf0fa 2281 {
7bfda7eb 2282 if (mode & M6812_OP_D_IDX)
60bcf0fa
NC
2283 {
2284 if (op->reg1 != REG_D)
2285 as_bad (_("Expecting register D for indexed indirect mode."));
6927f982 2286 if ((move_insn) && (!(current_architecture & cpu9s12x)))
60bcf0fa
NC
2287 as_bad (_("Indexed indirect mode is not allowed for movb/movw."));
2288
2289 byte = 0xE7;
2290 }
2291 else
2292 {
2293 switch (op->reg1)
2294 {
2295 case REG_A:
2296 byte = 0xE4;
2297 break;
2298
2299 case REG_B:
2300 byte = 0xE5;
2301 break;
2302
2303 default:
2304 as_bad (_("Invalid accumulator register."));
2305
2306 case REG_D:
2307 byte = 0xE6;
2308 break;
2309 }
2310 }
2311 switch (op->reg2)
2312 {
2313 case REG_X:
2314 break;
2315
2316 case REG_Y:
2317 byte |= (1 << 3);
2318 break;
2319
2320 case REG_SP:
2321 byte |= (2 << 3);
2322 break;
2323
2324 case REG_PC:
2325 byte |= (3 << 3);
2326 break;
2327
2328 default:
2329 as_bad (_("Invalid indexed register."));
2330 break;
2331 }
2332 f = frag_more (1);
2333 number_to_chars_bigendian (f, byte, 1);
2334 return 1;
2335 }
2336
6927f982
NC
2337 fprintf (stderr, "mode = 0x%x\nop->reg1 = 0x%x\nop->reg2 = 0x%x\n",
2338 mode, op->reg1, op->reg2);
60bcf0fa
NC
2339 as_fatal (_("Addressing mode not implemented yet."));
2340 return 0;
2341}
2342
2343/* Assemble the 68HC12 register mode byte. */
2344static int
ca43c854 2345build_reg_mode (operand *op, int format)
60bcf0fa
NC
2346{
2347 unsigned char byte;
2348 char *f;
2349
6927f982
NC
2350 if ((format & M6812_OP_SEX_MARKER)
2351 && (op->reg1 != REG_A) && (op->reg1 != REG_B) && (op->reg1 != REG_CCR)
2352 && (!(current_architecture & cpu9s12x)))
60bcf0fa
NC
2353 as_bad (_("Invalid source register for this instruction, use 'tfr'."));
2354 else if (op->reg1 == REG_NONE || op->reg1 == REG_PC)
2355 as_bad (_("Invalid source register."));
2356
2357 if (format & M6812_OP_SEX_MARKER
2358 && op->reg2 != REG_D
2359 && op->reg2 != REG_X && op->reg2 != REG_Y && op->reg2 != REG_SP)
2360 as_bad (_("Invalid destination register for this instruction, use 'tfr'."));
2361 else if (op->reg2 == REG_NONE || op->reg2 == REG_PC)
2362 as_bad (_("Invalid destination register."));
2363
2364 byte = (op->reg1 << 4) | (op->reg2);
2365 if (format & M6812_OP_EXG_MARKER)
2366 byte |= 0x80;
2367
6927f982
NC
2368 if ((format & M6812_OP_SEX_MARKER)
2369 && (op->reg1 == REG_D) && (current_architecture & cpu9s12x))
2370 byte |= 0x08;
2371
60bcf0fa
NC
2372 f = frag_more (1);
2373 number_to_chars_bigendian (f, byte, 1);
2374 return 1;
2375}
2376
6927f982
NC
2377/* build_insn_xg takes a pointer to the opcode entry in the opcode table,
2378 the array of operand expressions and builds the corresponding instruction. */
2379
2380static void
2381build_insn_xg (struct m68hc11_opcode *opcode,
2382 operand operands[],
2383 int nb_operands ATTRIBUTE_UNUSED)
2384{
2385 char *f;
2386 long format;
2387
2388 /* Put the page code instruction if there is one. */
2389 format = opcode->format;
2390
2391 if (!(operands[0].mode & (M6811_OP_LOW_ADDR | M6811_OP_HIGH_ADDR)))
2392 /* Need to retain those two modes, but clear for others. */
2393 operands[0].mode = 0;
2394
2395 if (format & M68XG_OP_R_IMM8)
2396 {
2397 /* These opcodes are byte followed by imm8. */
2398 f = m68hc11_new_insn (1);
2399 number_to_chars_bigendian (f, opcode->opcode >> 8, 1);
2400 fixup8_xg (&operands[0].exp, format, operands[0].mode);
2401 }
2402 else if (format & M68XG_OP_R_IMM16)
2403 {
2404 fixS *fixp;
2405 /* These opcodes expand into two imm8 instructions.
2406 Emit as low:high as per the Freescale datasheet.
2407 The linker requires them to be adjacent to handle the upper byte. */
2408
2409 /* Build low byte. */
2410 f = m68hc11_new_insn (1);
2411 number_to_chars_bigendian (f, opcode->opcode >> 8, 1);
2412 operands[0].mode = M6811_OP_LOW_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_LO8XG);
2416 fixp->fx_no_overflow = 1;
2417 number_to_chars_bigendian (f, 0, 1);
2418
2419 /* Build high byte. */
2420 f = m68hc11_new_insn (1);
2421 number_to_chars_bigendian (f, (opcode->opcode >> 8) | 0x08, 1);
2422 operands[0].mode = M6811_OP_HIGH_ADDR;
2423 f = frag_more (1);
2424 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
2425 &operands[0].exp, FALSE, BFD_RELOC_M68HC12_HI8XG);
2426 fixp->fx_no_overflow = 1;
2427 number_to_chars_bigendian (f, 0, 1);
2428
2429 }
2430 else if (format & M68XG_OP_REL9)
2431 {
2432 f = m68hc11_new_insn (1);
2433 number_to_chars_bigendian (f, opcode->opcode >> 8, 1); /* High byte. */
2434 fixup8_xg (&operands[0].exp, format, M68XG_OP_REL9);
2435 }
2436 else if (format & M68XG_OP_REL10)
2437 {
2438 f = m68hc11_new_insn (1);
2439 number_to_chars_bigendian (f, opcode->opcode >> 8, 1); /* High byte. */
2440 fixup8_xg (&operands[0].exp, format, M68XG_OP_REL10);
2441 }
2442 else
2443 {
2444 f = m68hc11_new_insn (2);
2445 number_to_chars_bigendian (f, opcode->opcode, 2);
2446 }
2447 return;
2448}
2449
60bcf0fa 2450/* build_insn takes a pointer to the opcode entry in the opcode table,
67c1ffbe 2451 the array of operand expressions and builds the corresponding instruction.
60bcf0fa
NC
2452 This operation only deals with non relative jumps insn (need special
2453 handling). */
6927f982 2454
60bcf0fa 2455static void
6927f982
NC
2456build_insn (struct m68hc11_opcode *opcode,
2457 operand operands[],
ca43c854 2458 int nb_operands ATTRIBUTE_UNUSED)
60bcf0fa
NC
2459{
2460 int i;
2461 char *f;
60bcf0fa
NC
2462 long format;
2463 int move_insn = 0;
2464
2465 /* Put the page code instruction if there is one. */
2466 format = opcode->format;
e371935f 2467
e371935f 2468 if (format & M6811_OP_BRANCH)
fd99afa7 2469 fix_new (frag_now, frag_now_fix (), 0,
e371935f
SC
2470 &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
2471
60bcf0fa
NC
2472 if (format & OP_EXTENDED)
2473 {
2474 int page_code;
2475
2476 f = m68hc11_new_insn (2);
2477 if (format & M6811_OP_PAGE2)
2478 page_code = M6811_OPCODE_PAGE2;
2479 else if (format & M6811_OP_PAGE3)
2480 page_code = M6811_OPCODE_PAGE3;
2481 else
2482 page_code = M6811_OPCODE_PAGE4;
2483
2484 number_to_chars_bigendian (f, page_code, 1);
2485 f++;
60bcf0fa
NC
2486 }
2487 else
2488 f = m68hc11_new_insn (1);
2489
2490 number_to_chars_bigendian (f, opcode->opcode, 1);
2491
2492 i = 0;
2493
2494 /* The 68HC12 movb and movw instructions are special. We have to handle
2495 them in a special way. */
2496 if (format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2))
2497 {
2498 move_insn = 1;
2499 if (format & M6812_OP_IDX)
2500 {
986c6f4b 2501 build_indexed_byte (&operands[0], format, 1);
60bcf0fa
NC
2502 i = 1;
2503 format &= ~M6812_OP_IDX;
2504 }
2505 if (format & M6812_OP_IDX_P2)
2506 {
986c6f4b 2507 build_indexed_byte (&operands[1], format, 1);
60bcf0fa
NC
2508 i = 0;
2509 format &= ~M6812_OP_IDX_P2;
2510 }
2511 }
2512
2513 if (format & (M6811_OP_DIRECT | M6811_OP_IMM8))
2514 {
60bcf0fa
NC
2515 fixup8 (&operands[i].exp,
2516 format & (M6811_OP_DIRECT | M6811_OP_IMM8 | M6812_OP_TRAP_ID),
2517 operands[i].mode);
2518 i++;
2519 }
7bfda7eb
SC
2520 else if (IS_CALL_SYMBOL (format) && nb_operands == 1)
2521 {
2522 format &= ~M6812_OP_PAGE;
2523 fixup24 (&operands[i].exp, format & M6811_OP_IND16,
2524 operands[i].mode);
2525 i++;
2526 }
60bcf0fa
NC
2527 else if (format & (M6811_OP_IMM16 | M6811_OP_IND16))
2528 {
7bfda7eb
SC
2529 fixup16 (&operands[i].exp,
2530 format & (M6811_OP_IMM16 | M6811_OP_IND16 | M6812_OP_PAGE),
60bcf0fa
NC
2531 operands[i].mode);
2532 i++;
2533 }
2534 else if (format & (M6811_OP_IX | M6811_OP_IY))
2535 {
2536 if ((format & M6811_OP_IX) && (operands[0].reg1 != REG_X))
2537 as_bad (_("Invalid indexed register, expecting register X."));
2538 if ((format & M6811_OP_IY) && (operands[0].reg1 != REG_Y))
2539 as_bad (_("Invalid indexed register, expecting register Y."));
2540
60bcf0fa
NC
2541 fixup8 (&operands[0].exp, M6811_OP_IX, operands[0].mode);
2542 i = 1;
2543 }
2544 else if (format &
7bfda7eb
SC
2545 (M6812_OP_IDX | M6812_OP_IDX_2 | M6812_OP_IDX_1
2546 | M6812_OP_D_IDX | M6812_OP_D_IDX_2))
60bcf0fa 2547 {
986c6f4b 2548 build_indexed_byte (&operands[i], format, move_insn);
60bcf0fa
NC
2549 i++;
2550 }
2551 else if (format & M6812_OP_REG && current_architecture & cpu6812)
2552 {
986c6f4b 2553 build_reg_mode (&operands[i], format);
60bcf0fa
NC
2554 i++;
2555 }
2556 if (format & M6811_OP_BITMASK)
2557 {
60bcf0fa
NC
2558 fixup8 (&operands[i].exp, M6811_OP_BITMASK, operands[i].mode);
2559 i++;
2560 }
2561 if (format & M6811_OP_JUMP_REL)
2562 {
60bcf0fa 2563 fixup8 (&operands[i].exp, M6811_OP_JUMP_REL, operands[i].mode);
60bcf0fa
NC
2564 }
2565 else if (format & M6812_OP_IND16_P2)
2566 {
60bcf0fa
NC
2567 fixup16 (&operands[1].exp, M6811_OP_IND16, operands[1].mode);
2568 }
7bfda7eb
SC
2569 if (format & M6812_OP_PAGE)
2570 {
2571 fixup8 (&operands[i].exp, M6812_OP_PAGE, operands[i].mode);
2572 }
60bcf0fa 2573}
60bcf0fa
NC
2574\f
2575/* Opcode identification and operand analysis. */
2576
2577/* find() gets a pointer to an entry in the opcode table. It must look at all
2578 opcodes with the same name and use the operands to choose the correct
2579 opcode. Returns the opcode pointer if there was a match and 0 if none. */
2580static struct m68hc11_opcode *
ca43c854 2581find (struct m68hc11_opcode_def *opc, operand operands[], int nb_operands)
60bcf0fa
NC
2582{
2583 int i, match, pos;
2584 struct m68hc11_opcode *opcode;
2585 struct m68hc11_opcode *op_indirect;
2586
2587 op_indirect = 0;
2588 opcode = opc->opcode;
2589
6927f982
NC
2590 /* Now search the opcode table table for one with operands
2591 that matches what we've got. */
2592
2593 if (current_architecture & cpuxgate)
2594 {
2595 /* Many XGATE insns are simple enough that we get an exact match. */
2596 for (pos = match = 0; match == 0 && pos < opc->nb_modes; pos++, opcode++)
2597 if (opcode->format == operands[nb_operands-1].mode)
2598 return opcode;
2599
2600 return 0;
2601 }
2602
2603 /* Non XGATE */
2604
60bcf0fa
NC
2605 /* Now search the opcode table table for one with operands
2606 that matches what we've got. We're only done if the operands matched so
2607 far AND there are no more to check. */
2608 for (pos = match = 0; match == 0 && pos < opc->nb_modes; pos++, opcode++)
2609 {
2610 int poss_indirect = 0;
2611 long format = opcode->format;
2612 int expect;
2613
2614 expect = 0;
2615 if (opcode->format & M6811_OP_MASK)
2616 expect++;
2617 if (opcode->format & M6811_OP_BITMASK)
2618 expect++;
2619 if (opcode->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
2620 expect++;
2621 if (opcode->format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2))
2622 expect++;
7bfda7eb
SC
2623 if ((opcode->format & M6812_OP_PAGE)
2624 && (!IS_CALL_SYMBOL (opcode->format) || nb_operands == 2))
2625 expect++;
60bcf0fa
NC
2626
2627 for (i = 0; expect == nb_operands && i < nb_operands; i++)
2628 {
2629 int mode = operands[i].mode;
2630
2631 if (mode & M6811_OP_IMM16)
2632 {
2633 if (format &
2634 (M6811_OP_IMM8 | M6811_OP_IMM16 | M6811_OP_BITMASK))
2635 continue;
2636 break;
2637 }
2638 if (mode == M6811_OP_DIRECT)
2639 {
2640 if (format & M6811_OP_DIRECT)
2641 continue;
2642
2643 /* If the operand is a page 0 operand, remember a
2644 possible <abs-16> addressing mode. We mark
2645 this and continue to check other operands. */
2646 if (format & M6811_OP_IND16
2647 && flag_strict_direct_addressing && op_indirect == 0)
2648 {
2649 poss_indirect = 1;
2650 continue;
2651 }
2652 break;
2653 }
2654 if (mode & M6811_OP_IND16)
2655 {
2656 if (i == 0 && (format & M6811_OP_IND16) != 0)
2657 continue;
7bfda7eb
SC
2658 if (i != 0 && (format & M6812_OP_PAGE) != 0)
2659 continue;
60bcf0fa
NC
2660 if (i != 0 && (format & M6812_OP_IND16_P2) != 0)
2661 continue;
2662 if (i == 0 && (format & M6811_OP_BITMASK))
2663 break;
2664 }
2665 if (mode & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
2666 {
2667 if (format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
2668 continue;
2669 }
2670 if (mode & M6812_OP_REG)
2671 {
df86943d
NC
2672 if (i == 0
2673 && (format & M6812_OP_REG)
2674 && (operands[i].reg2 == REG_NONE))
60bcf0fa 2675 continue;
df86943d
NC
2676 if (i == 0
2677 && (format & M6812_OP_REG)
2678 && (format & M6812_OP_REG_2)
2679 && (operands[i].reg2 != REG_NONE))
60bcf0fa 2680 continue;
df86943d
NC
2681 if (i == 0
2682 && (format & M6812_OP_IDX)
2683 && (operands[i].reg2 != REG_NONE))
2684 continue;
df86943d
NC
2685 if (i == 0
2686 && (format & M6812_OP_IDX)
60bcf0fa
NC
2687 && (format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2)))
2688 continue;
df86943d
NC
2689 if (i == 1
2690 && (format & M6812_OP_IDX_P2))
60bcf0fa
NC
2691 continue;
2692 break;
2693 }
2694 if (mode & M6812_OP_IDX)
2695 {
2696 if (format & M6811_OP_IX && operands[i].reg1 == REG_X)
2697 continue;
2698 if (format & M6811_OP_IY && operands[i].reg1 == REG_Y)
2699 continue;
2700 if (i == 0
2701 && format & (M6812_OP_IDX | M6812_OP_IDX_1 | M6812_OP_IDX_2)
2702 && (operands[i].reg1 == REG_X
2703 || operands[i].reg1 == REG_Y
2704 || operands[i].reg1 == REG_SP
2705 || operands[i].reg1 == REG_PC))
2706 continue;
6927f982 2707 if (i == 1 && (format & M6812_OP_IDX_P2))
60bcf0fa
NC
2708 continue;
2709 }
7bfda7eb
SC
2710 if (mode & format & (M6812_OP_D_IDX | M6812_OP_D_IDX_2))
2711 {
2712 if (i == 0)
2713 continue;
2714 }
60bcf0fa
NC
2715 if (mode & M6812_AUTO_INC_DEC)
2716 {
2717 if (i == 0
2718 && format & (M6812_OP_IDX | M6812_OP_IDX_1 |
2719 M6812_OP_IDX_2))
2720 continue;
2721 if (i == 1 && format & M6812_OP_IDX_P2)
2722 continue;
2723 }
2724 break;
2725 }
2726 match = i == nb_operands;
2727
2728 /* Operands are ok but an operand uses page 0 addressing mode
2729 while the insn supports abs-16 mode. Keep a reference to this
2730 insns in case there is no insn supporting page 0 addressing. */
2731 if (match && poss_indirect)
2732 {
2733 op_indirect = opcode;
2734 match = 0;
2735 }
2736 if (match)
2737 break;
2738 }
2739
2740 /* Page 0 addressing is used but not supported by any insn.
2741 If absolute addresses are supported, we use that insn. */
2742 if (match == 0 && op_indirect)
2743 {
2744 opcode = op_indirect;
2745 match = 1;
2746 }
2747
6927f982 2748 return match ? opcode : 0;
60bcf0fa
NC
2749}
2750
60bcf0fa
NC
2751/* Find the real opcode and its associated operands. We use a progressive
2752 approach here. On entry, 'opc' points to the first opcode in the
2753 table that matches the opcode name in the source line. We try to
2754 isolate an operand, find a possible match in the opcode table.
2755 We isolate another operand if no match were found. The table 'operands'
2756 is filled while operands are recognized.
2757
2758 Returns the opcode pointer that matches the opcode name in the
2759 source line and the associated operands. */
2760static struct m68hc11_opcode *
ca43c854
SC
2761find_opcode (struct m68hc11_opcode_def *opc, operand operands[],
2762 int *nb_operands)
60bcf0fa
NC
2763{
2764 struct m68hc11_opcode *opcode;
2765 int i;
2766
2767 if (opc->max_operands == 0)
2768 {
2769 *nb_operands = 0;
2770 return opc->opcode;
2771 }
2772
2773 for (i = 0; i < opc->max_operands;)
2774 {
2775 int result;
2776
2777 result = get_operand (&operands[i], i, opc->format);
2778 if (result <= 0)
fafb6d17 2779 return 0;
60bcf0fa
NC
2780
2781 /* Special case where the bitmask of the bclr/brclr
2782 instructions is not introduced by #.
2783 Example: bclr 3,x $80. */
2784 if (i == 1 && (opc->format & M6811_OP_BITMASK)
2785 && (operands[i].mode & M6811_OP_IND16))
2786 {
2787 operands[i].mode = M6811_OP_IMM16;
2788 }
2789
2790 i += result;
2791 *nb_operands = i;
2792 if (i >= opc->min_operands)
2793 {
2794 opcode = find (opc, operands, i);
577300ce
SC
2795
2796 /* Another special case for 'call foo,page' instructions.
2797 Since we support 'call foo' and 'call foo,page' we must look
2798 if the optional page specification is present otherwise we will
2799 assemble immediately and treat the page spec as garbage. */
7bfda7eb
SC
2800 if (opcode && !(opcode->format & M6812_OP_PAGE))
2801 return opcode;
2802
2803 if (opcode && *input_line_pointer != ',')
fafb6d17 2804 return opcode;
60bcf0fa
NC
2805 }
2806
2807 if (*input_line_pointer == ',')
2808 input_line_pointer++;
2809 }
82efde3a 2810
60bcf0fa
NC
2811 return 0;
2812}
2813
2814#define M6812_XBCC_MARKER (M6812_OP_TBCC_MARKER \
2815 | M6812_OP_DBCC_MARKER \
2816 | M6812_OP_IBCC_MARKER)
60bcf0fa
NC
2817\f
2818/* Gas line assembler entry point. */
2819
2820/* This is the main entry point for the machine-dependent assembler. str
2821 points to a machine-dependent instruction. This function is supposed to
2822 emit the frags/bytes it assembles to. */
2823void
ca43c854 2824md_assemble (char *str)
60bcf0fa
NC
2825{
2826 struct m68hc11_opcode_def *opc;
2827 struct m68hc11_opcode *opcode;
2828
6927f982 2829 struct m68hc11_opcode opcode_local;
2132e3a3
AM
2830 unsigned char *op_start, *op_end;
2831 char *save;
60bcf0fa
NC
2832 char name[20];
2833 int nlen = 0;
2834 operand operands[M6811_MAX_OPERANDS];
878bcc43 2835 int nb_operands = 0;
60bcf0fa
NC
2836 int branch_optimize = 0;
2837 int alias_id = -1;
2838
fafb6d17 2839 /* Drop leading whitespace. */
60bcf0fa
NC
2840 while (*str == ' ')
2841 str++;
2842
2843 /* Find the opcode end and get the opcode in 'name'. The opcode is forced
2844 lower case (the opcode table only has lower case op-codes). */
2132e3a3 2845 for (op_start = op_end = (unsigned char *) str;
4ad7ac30 2846 *op_end && !is_end_of_line[*op_end] && *op_end != ' ';
60bcf0fa
NC
2847 op_end++)
2848 {
3882b010 2849 name[nlen] = TOLOWER (op_start[nlen]);
60bcf0fa 2850 nlen++;
4ad7ac30
AM
2851 if (nlen == sizeof (name) - 1)
2852 break;
60bcf0fa
NC
2853 }
2854 name[nlen] = 0;
2855
2856 if (nlen == 0)
2857 {
2858 as_bad (_("No instruction or missing opcode."));
2859 return;
2860 }
2861
6927f982
NC
2862 if (current_architecture == cpuxgate)
2863 {
2864 /* Find the opcode definition given its name. */
2865 opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash, name);
2866 if (opc == NULL)
2867 {
2868 as_bad (_("Opcode `%s' is not recognized."), name);
2869 return;
2870 }
2871
2872 /* Grab a local copy. */
2873 opcode_local.name = opc->opcode->name;
2874 /* These will be incomplete where multiple variants exist. */
2875 opcode_local.opcode = opc->opcode->opcode;
2876 opcode_local.format = opc->opcode->format;
2877
2878 save = input_line_pointer;
2879 input_line_pointer = (char *) op_end;
2880
2881 if (opc->format == M68XG_OP_NONE)
2882 {
2883 /* No special handling required. */
2884 opcode_local.format = M68XG_OP_NONE;
2885 build_insn_xg (opc->opcode, operands, 0);
2886 return;
2887 }
2888
2889 /* Special handling of TFR. */
2890 if (strncmp (opc->opcode->name, "tfr",3) == 0)
2891 {
2892 /* There must be two operands with a comma. */
2893 input_line_pointer = skip_whites (input_line_pointer);
2894 operands[0].reg1 = register_name ();
2895 if (operands[0].reg1 == REG_NONE)
2896 {
2897 as_bad ("Invalid register\n");
2898 return;
2899 }
2900 input_line_pointer = skip_whites (input_line_pointer);
2901 if (*input_line_pointer != ',')
2902 {
2903 as_bad ("Missing comma.\n");
2904 return;
2905 }
2906 input_line_pointer++;
2907 input_line_pointer = skip_whites (input_line_pointer);
2908 operands[1].reg1 = register_name ();
2909 if (operands[1].reg1 == REG_NONE)
2910 {
2911 as_bad ("Invalid register\n");
2912 return;
2913 }
2914 input_line_pointer = skip_whites (input_line_pointer);
2915 if (*input_line_pointer != '\n' && *input_line_pointer)
2916 {
2917 as_bad (_("Garbage at end of instruction: `%s'."),
2918 input_line_pointer);
2919 return;
2920 }
2921 if (operands[1].reg1 == REG_CCR) /* ,CCR */
2922 opc->opcode->opcode = 0x00f8 | ( operands[0].reg1 << 8);
2923 else if (operands[0].reg1 == REG_CCR) /* CCR, */
2924 opc->opcode->opcode = 0x00f9 | ( operands[1].reg1 << 8);
2925 else if (operands[1].reg1 == REG_PC) /* ,PC */
2926 opc->opcode->opcode = 0x00fa | ( operands[0].reg1 << 8);
2927 else
2928 {
2929 as_bad ("Invalid operand to TFR\n");
2930 return;
2931 }
2932 /* no special handling required */
2933 opcode_local.format = M68XG_OP_NONE;
2934 opcode_local.opcode = opc->opcode->opcode;
2935 build_insn_xg (&opcode_local, operands, 0);
2936 return;
2937 }
2938
2939 /* CSEM, SSEM */
2940 if (opc->format & M68XG_OP_IMM3)
2941 {
2942 /* Either IMM3 or R */
2943 input_line_pointer = skip_whites (input_line_pointer);
2944 if ((*input_line_pointer == 'R') || (*input_line_pointer == 'r'))
2945 {
2946 operands[0].reg1 = register_name ();
2947 if (operands[0].reg1 == REG_NONE)
2948 {
2949 as_bad ("Invalid register\n");
2950 return;
2951 }
2952 operands[0].mode = M68XG_OP_R;
2953 /* One opcode has multiple modes, so find right one. */
2954 opcode = find (opc, operands, 1);
2955 if (opcode)
2956 {
2957 opcode_local.opcode = opcode->opcode
2958 | (operands[0].reg1 << 8);
2959 opcode_local.format = M68XG_OP_NONE;
2960 build_insn_xg (&opcode_local, operands, 1);
2961 }
2962 else
2963 as_bad ("No opcode found\n");
2964
2965 return;
2966 }
2967 else
2968 {
2969 if (*input_line_pointer == '#')
2970 input_line_pointer++;
2971
2972 expression (&operands[0].exp);
2973 if (operands[0].exp.X_op == O_illegal)
2974 {
2975 as_bad (_("Illegal operand."));
2976 return;
2977 }
2978 else if (operands[0].exp.X_op == O_absent)
2979 {
2980 as_bad (_("Missing operand."));
2981 return;
2982 }
2983
2984 if (check_range (operands[0].exp.X_add_number,M68XG_OP_IMM3))
2985 {
2986 opcode_local.opcode |= (operands[0].exp.X_add_number);
2987 operands[0].mode = M68XG_OP_IMM3;
2988
2989 opcode = find (opc, operands, 1);
2990 if (opcode)
2991 {
2992 opcode_local.opcode = opcode->opcode;
2993 opcode_local.opcode
2994 |= (operands[0].exp.X_add_number) << 8;
2995 opcode_local.format = M68XG_OP_NONE;
2996 build_insn_xg (&opcode_local, operands, 1);
2997 }
2998 else
2999 as_bad ("No opcode found\n");
3000
3001 return;
3002 }
3003 else
3004 {
3005 as_bad ("Number out of range for IMM3\n");
3006 return;
3007 }
3008 }
3009 }
3010
3011 /* Special handling of SIF. */
3012 if (strncmp (opc->opcode->name, "sif",3) == 0)
3013 {
3014 /* Either OP_NONE or OP_RS. */
3015 if (*input_line_pointer != '\n')
3016 input_line_pointer = skip_whites (input_line_pointer);
3017
3018 if ((*input_line_pointer == '\n') || (*input_line_pointer == '\r')
3019 || (*input_line_pointer == '\0'))
3020 opc->opcode->opcode = 0x0300;
3021 else
3022 {
3023 operands[0].reg1 = register_name ();
3024 if (operands[0].reg1 == REG_NONE)
3025 {
3026 as_bad ("Invalid register\n");
3027 return;
3028 }
3029 opcode_local.opcode = 0x00f7 | (operands[0].reg1 << 8);
3030 }
3031 opcode_local.format = M68XG_OP_NONE;
3032 build_insn_xg (&opcode_local, operands, 0);
3033 return;
3034 }
3035
3036 /* SEX, PAR, JAL plus aliases NEG, TST, COM */
3037 if (opc->format & M68XG_OP_R)
3038 {
3039 input_line_pointer = skip_whites (input_line_pointer);
3040 operands[0].reg1 = register_name ();
3041 if (operands[0].reg1 == REG_NONE)
3042 {
3043 as_bad ("Invalid register\n");
3044 return;
3045 }
3046 if ((*input_line_pointer == '\n') || (*input_line_pointer == '\r')
3047 || (*input_line_pointer == '\0'))
3048 {
3049 /* Likely to be OP R. */
3050 if (opc->format & M68XG_OP_R)
3051 {
3052 operands[0].mode = M68XG_OP_R;
3053
3054 opcode = find (opc, operands, 1);
3055 if (opcode)
3056 {
3057 if ((strncmp (opc->opcode->name, "com",3) == 0)
3058 || (strncmp (opc->opcode->name, "neg",3) == 0))
3059 /* Special case for com RD as alias for sub RD,R0,RS */
3060 /* Special case for neg RD as alias for sub RD,R0,RS */
3061 opcode_local.opcode = opcode->opcode
3062 | (operands[0].reg1 << 8) | (operands[0].reg1 << 2);
3063 else if (strncmp (opc->opcode->name, "tst",3) == 0)
3064 /* Special case for tst RS alias for sub R0, RS, R0 */
3065 opcode_local.opcode = opcode->opcode
3066 | (operands[0].reg1 << 5);
3067 else
3068 opcode_local.opcode |= (operands[0].reg1 << 8);
3069 }
3070 opcode_local.format = M68XG_OP_NONE;
3071 build_insn_xg (&opcode_local, operands, 0);
3072 }
3073 else
3074 as_bad ("No valid mode found\n");
3075
3076 return;
3077 }
3078 }
3079
3080 if (opc->format & (M68XG_OP_REL9 | M68XG_OP_REL10))
3081 {
3082 opcode_local.format = opc->format;
3083 input_line_pointer = skip_whites (input_line_pointer);
3084 expression (&operands[0].exp);
3085 if (operands[0].exp.X_op == O_illegal)
3086 {
3087 as_bad (_("Illegal operand."));
3088 return;
3089 }
3090 else if (operands[0].exp.X_op == O_absent)
3091 {
3092 as_bad (_("Missing operand."));
3093 return;
3094 }
3095 opcode_local.opcode = opc->opcode->opcode;
3096 build_insn_xg (&opcode_local, operands, 1);
3097 return;
3098 }
3099
3100
3101 /* For other command formats, parse input line and determine the mode
3102 we are using as we go. */
3103
3104 input_line_pointer = skip_whites (input_line_pointer);
3105 if ((*input_line_pointer == '\n') || (*input_line_pointer == '\r')
3106 || (*input_line_pointer == '\0'))
3107 return; /* nothing left */
3108
3109 if (*input_line_pointer == '#')
3110 {
3111 as_bad ("No register specified before hash\n");
3112 return;
3113 }
3114
3115 /* first operand is expected to be a register */
3116 if ((*input_line_pointer == 'R') || (*input_line_pointer == 'r'))
3117 {
3118 operands[0].reg1 = register_name ();
3119 if (operands[0].reg1 == REG_NONE)
3120 {
3121 as_bad ("Invalid register\n");
3122 return;
3123 }
3124 }
3125
3126 input_line_pointer = skip_whites (input_line_pointer);
3127 if (*input_line_pointer != ',')
3128 {
3129 as_bad ("Missing operand\n");
3130 return;
3131 }
3132 input_line_pointer++;
3133 input_line_pointer = skip_whites (input_line_pointer);
3134
3135 if (*input_line_pointer == '#')
3136 {
3137 /* Some kind of immediate mode, check if this is possible. */
3138 if (!(opc->format
3139 & (M68XG_OP_R_IMM8 | M68XG_OP_R_IMM16 | M68XG_OP_R_IMM4)))
3140 as_bad ("Invalid immediate mode for `%s'", opc->opcode->name);
3141 else
3142 {
3143 input_line_pointer++;
3144 input_line_pointer = skip_whites (input_line_pointer);
3145 if (strncmp (input_line_pointer, "%hi", 3) == 0)
3146 {
3147 input_line_pointer += 3;
3148 operands[0].mode = M6811_OP_HIGH_ADDR;
3149 }
3150 else if (strncmp (input_line_pointer, "%lo", 3) == 0)
3151 {
3152 input_line_pointer += 3;
3153 operands[0].mode = M6811_OP_LOW_ADDR;
3154 }
3155 else
3156 operands[0].mode = 0;
3157
3158 expression (&operands[0].exp);
3159 if (operands[0].exp.X_op == O_illegal)
3160 {
3161 as_bad (_("Illegal operand."));
3162 return;
3163 }
3164 else if (operands[0].exp.X_op == O_absent)
3165 {
3166 as_bad (_("Missing operand."));
3167 return;
3168 }
3169 /* ok so far, can only be one mode */
3170 opcode_local.format = opc->format
3171 & (M68XG_OP_R_IMM8 | M68XG_OP_R_IMM16 | M68XG_OP_R_IMM4);
3172 if (opcode_local.format & M68XG_OP_R_IMM4)
3173 {
3174 operands[0].mode = M68XG_OP_R_IMM4;
3175 /* same opcodes have multiple modes, so find right one */
3176 opcode = find (opc, operands, 1);
3177 if (opcode)
3178 opcode_local.opcode = opcode->opcode
3179 | (operands[0].reg1 << 8);
3180
3181 if (operands[0].exp.X_op != O_constant)
3182 as_bad ("Only constants supported at for IMM4 mode\n");
3183 else
3184 {
3185 if (check_range
3186 (operands[0].exp.X_add_number,M68XG_OP_R_IMM4))
3187 opcode_local.opcode
3188 |= (operands[0].exp.X_add_number << 4);
3189 else
3190 as_bad ("Number out of range for IMM4\n");
3191 }
3192 opcode_local.format = M68XG_OP_NONE;
3193 }
3194 else if (opcode_local.format & M68XG_OP_R_IMM16)
3195 {
3196 operands[0].mode = M68XG_OP_R_IMM16;
3197
3198 opcode = find (opc, operands, 1);
3199 if (opcode)
3200 {
3201 opcode_local.opcode = opcode->opcode
3202 | (operands[0].reg1 << 8);
3203 }
3204 }
3205 else
3206 {
3207 opcode_local.opcode = opc->opcode->opcode
3208 | (operands[0].reg1 << 8);
3209 }
3210 build_insn_xg (&opcode_local, operands, 1);
3211 }
3212 }
3213 else if ((*input_line_pointer == 'R') || (*input_line_pointer == 'r'))
3214 {
3215 /* we've got as far as OP R, R */
3216 operands[1].reg1 = register_name ();
3217 if (operands[1].reg1 == REG_NONE)
3218 {
3219 as_bad ("Invalid register\n");
3220 return;
3221 }
3222 if ((*input_line_pointer == '\n') || (*input_line_pointer == '\r')
3223 || (*input_line_pointer == '\0'))
3224 {
3225 /* looks like OP_R_R */
3226 if (opc->format & M68XG_OP_R_R)
3227 {
3228 operands[0].mode = M68XG_OP_R_R;
3229 /* same opcodes have multiple modes, so find right one */
3230 opcode = find (opc, operands, 1);
3231 if (opcode)
3232 {
3233 if ((strncmp (opc->opcode->name, "com",3) == 0)
3234 || (strncmp (opc->opcode->name, "mov",3) == 0)
3235 || (strncmp (opc->opcode->name, "neg",3) == 0))
3236 {
3237 /* Special cases for:
3238 com RD, RS alias for xnor RD,R0,RS
3239 mov RD, RS alias for or RD, R0, RS
3240 neg RD, RS alias for sub RD, R0, RS */
3241 opcode_local.opcode = opcode->opcode
3242 | (operands[0].reg1 << 8) | (operands[1].reg1 << 2);
3243 }
3244 else if ((strncmp (opc->opcode->name, "cmp",3) == 0)
3245 || (strncmp (opc->opcode->name, "cpc",3) == 0))
3246 {
3247 /* special cases for:
3248 cmp RS1, RS2 alias for sub R0, RS1, RS2
3249 cpc RS1, RS2 alias for sbc R0, RS1, RS2 */
3250 opcode_local.opcode = opcode->opcode
3251 | (operands[0].reg1 << 5) | (operands[1].reg1 << 2);
3252 }
3253 else
3254 {
3255 opcode_local.opcode = opcode->opcode
3256 | (operands[0].reg1 << 8) | (operands[1].reg1 << 5);
3257 }
3258 opcode_local.format = M68XG_OP_NONE;
3259 build_insn_xg (&opcode_local, operands, 1);
3260 }
3261 }
3262 else
3263 {
3264 as_bad ("No valid mode found\n");
3265 }
3266 }
3267 else
3268 {
3269 /* more data */
3270 if (*input_line_pointer != ',')
3271 {
3272 as_bad (_("Missing operand."));
3273 return;
3274 }
3275 input_line_pointer++;
3276 input_line_pointer = skip_whites (input_line_pointer);
3277 if ((*input_line_pointer == 'R') || (*input_line_pointer == 'r'))
3278 {
3279 operands[2].reg1 = register_name ();
3280 if (operands[2].reg1 == REG_NONE)
3281 {
3282 as_bad ("Invalid register\n");
3283 return;
3284 }
3285 if (opc->format & M68XG_OP_R_R_R)
3286 {
3287 operands[0].mode = M68XG_OP_R_R_R;
3288
3289 opcode = find (opc, operands, 1);
3290 if (opcode)
3291 {
3292 opcode_local.opcode = opcode->opcode
3293 | (operands[0].reg1 << 8) | (operands[1].reg1 << 5)
3294 | (operands[2].reg1 << 2);
3295 opcode_local.format = M68XG_OP_NONE;
3296 build_insn_xg (&opcode_local, operands, 1);
3297 }
3298 }
3299 else
3300 {
3301 as_bad ("No valid mode found\n");
3302 }
3303 }
3304 }
3305 }
3306 else if (*input_line_pointer == '(') /* Indexed modes */
3307 {
3308 input_line_pointer++;
3309 input_line_pointer = skip_whites (input_line_pointer);
3310 if ((*input_line_pointer == 'R') || (*input_line_pointer == 'r'))
3311 {
3312 /* we've got as far as OP R, (R */
3313 operands[1].reg1 = register_name ();
3314 if (operands[1].reg1 == REG_NONE)
3315 {
3316 as_bad ("Invalid register\n");
3317 return;
3318 }
3319
3320 if ((*input_line_pointer == '\n') || (*input_line_pointer == '\r')
3321 || (*input_line_pointer == '\0'))
3322 {
3323 /* Looks like OP_R_R. */
3324 as_bad (_("Missing operand."));
3325 return;
3326 }
3327
3328 input_line_pointer = skip_whites (input_line_pointer);
3329
3330 if (*input_line_pointer != ',')
3331 {
3332 as_bad (_("Missing operand."));
3333 return;
3334 }
3335 input_line_pointer++;
3336 input_line_pointer = skip_whites (input_line_pointer);
3337
3338 if (*input_line_pointer == '#')
3339 {
3340 input_line_pointer++;
3341 input_line_pointer = skip_whites (input_line_pointer);
3342 expression (&operands[0].exp);
3343 if (operands[0].exp.X_op == O_illegal)
3344 {
3345 as_bad (_("Illegal operand."));
3346 return;
3347 }
3348 else if (operands[0].exp.X_op == O_absent)
3349 {
3350 as_bad (_("Missing operand."));
3351 return;
3352 }
3353
3354 input_line_pointer = skip_whites (input_line_pointer);
3355 if (*input_line_pointer != ')')
3356 {
3357 as_bad ("Missing `)' to close register indirect operand.");
3358 return;
3359 }
3360 else
3361 {
3362 input_line_pointer++;
3363 }
3364
3365 /* Ok so far, can only be one mode. */
3366 opcode_local.format = M68XG_OP_R_R_OFFS5;
3367 operands[0].mode = M68XG_OP_R_R_OFFS5;
3368
3369 opcode = find (opc, operands, 1);
3370 if (opcode)
3371 {
3372 opcode_local.opcode = opcode->opcode
3373 | (operands[0].reg1 << 8) | (operands[1].reg1 << 5);
3374 if (operands[0].exp.X_op != O_constant)
3375 {
3376 as_bad
3377 ("Only constants supported for indexed OFFS5 mode\n");
3378 }
3379 else
3380 {
3381 if (check_range (operands[0].exp.X_add_number,
3382 M68XG_OP_R_R_OFFS5))
3383 {
3384 opcode_local.opcode
3385 |= (operands[0].exp.X_add_number);
3386 opcode_local.format = M68XG_OP_NONE;
3387 build_insn_xg (&opcode_local, operands, 1);
3388 }
3389 else
3390 {
3391 as_bad ("Number out of range for OFFS5\n");
3392 }
3393 }
3394 }
3395 }
3396 else
3397 {
3398 operands[0].mode = M68XG_OP_RD_RB_RI;
3399
3400 if (*input_line_pointer == '-')
3401 {
3402 operands[0].mode = M68XG_OP_RD_RB_mRI;
3403 input_line_pointer++;
3404 }
3405 operands[2].reg1 = register_name ();
3406 if (operands[2].reg1 == REG_NONE)
3407 {
3408 as_bad ("Invalid register\n");
3409 return;
3410 }
3411
3412 if (*input_line_pointer == '+')
3413 {
3414 if (opcode_local.format == M68XG_OP_RD_RB_mRI)
3415 {
3416 as_bad (_("Illegal operand."));
3417 return;
3418 }
3419 operands[0].mode = M68XG_OP_RD_RB_RIp;
3420 input_line_pointer++;
3421 }
3422
3423 input_line_pointer = skip_whites (input_line_pointer);
3424 if (*input_line_pointer != ')')
3425 {
3426 as_bad
3427 ("Missing `)' to close register indirect operand.");
3428 return;
3429 }
3430 else
3431 {
3432 input_line_pointer++;
3433 }
3434
3435 opcode = find (opc, operands, 1);
3436 if (opcode)
3437 {
3438 opcode_local.opcode = opcode->opcode
3439 | (operands[0].reg1 << 8) | (operands[1].reg1 << 5)
3440 | (operands[2].reg1 << 2);
3441 opcode_local.format = M68XG_OP_NONE;
3442 build_insn_xg (&opcode_local, operands, 1);
3443 }
3444 else
3445 {
3446 as_bad ("Failed to find opcode for %s %s\n",
3447 opc->opcode->name, (char *)op_end);
3448 }
3449 }
3450 }
3451 }
3452 else
3453 {
3454 as_bad (_("Failed to find a valid mode for `%s'."),
3455 opc->opcode->name);
3456 }
3457
3458 if (opc->opcode && !flag_mri)
3459 {
3460 char *p = input_line_pointer;
3461
3462 while (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r')
3463 p++;
3464
3465 if (*p != '\n' && *p)
3466 as_bad (_("Garbage at end of instruction: `%s'."), p);
3467 }
3468
3469 input_line_pointer = save;
3470
3471 /* Opcode is known but does not have valid operands. Print out the
3472 syntax for this opcode. */
3473 if (opc->opcode == 0)
3474 {
3475 if (flag_print_insn_syntax)
3476 print_insn_format (name);
3477
3478 as_bad (_("Invalid operand for `%s'"), name);
3479 return;
3480 }
3481
3482 return;
3483 }
3484
60bcf0fa
NC
3485 /* Find the opcode definition given its name. */
3486 opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash, name);
3487
3488 /* If it's not recognized, look for 'jbsr' and 'jbxx'. These are
1370e33d
NC
3489 pseudo insns for relative branch. For these branches, we always
3490 optimize them (turned into absolute branches) even if --short-branches
60bcf0fa
NC
3491 is given. */
3492 if (opc == NULL && name[0] == 'j' && name[1] == 'b')
3493 {
3494 opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash, &name[1]);
3495 if (opc
3496 && (!(opc->format & M6811_OP_JUMP_REL)
3497 || (opc->format & M6811_OP_BITMASK)))
3498 opc = 0;
3499 if (opc)
3500 branch_optimize = 1;
3501 }
3502
6927f982 3503 /* The following test should probably be removed. This does not conform
60bcf0fa
NC
3504 to Motorola assembler specs. */
3505 if (opc == NULL && flag_mri)
3506 {
3507 if (*op_end == ' ' || *op_end == '\t')
3508 {
3509 while (*op_end == ' ' || *op_end == '\t')
3510 op_end++;
3511
3512 if (nlen < 19
3513 && (*op_end &&
3514 (is_end_of_line[op_end[1]]
3515 || op_end[1] == ' ' || op_end[1] == '\t'
3882b010 3516 || !ISALNUM (op_end[1])))
60bcf0fa
NC
3517 && (*op_end == 'a' || *op_end == 'b'
3518 || *op_end == 'A' || *op_end == 'B'
3519 || *op_end == 'd' || *op_end == 'D'
3520 || *op_end == 'x' || *op_end == 'X'
3521 || *op_end == 'y' || *op_end == 'Y'))
3522 {
3882b010 3523 name[nlen++] = TOLOWER (*op_end++);
60bcf0fa
NC
3524 name[nlen] = 0;
3525 opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash,
3526 name);
3527 }
3528 }
3529 }
3530
3531 /* Identify a possible instruction alias. There are some on the
986c6f4b 3532 68HC12 to emulate a few 68HC11 instructions. */
60bcf0fa
NC
3533 if (opc == NULL && (current_architecture & cpu6812))
3534 {
3535 int i;
3536
3537 for (i = 0; i < m68hc12_num_alias; i++)
3538 if (strcmp (m68hc12_alias[i].name, name) == 0)
3539 {
3540 alias_id = i;
3541 break;
3542 }
3543 }
3544 if (opc == NULL && alias_id < 0)
3545 {
3546 as_bad (_("Opcode `%s' is not recognized."), name);
3547 return;
3548 }
3549 save = input_line_pointer;
2132e3a3 3550 input_line_pointer = (char *) op_end;
60bcf0fa
NC
3551
3552 if (opc)
3553 {
3554 opc->used++;
3555 opcode = find_opcode (opc, operands, &nb_operands);
3556 }
3557 else
3558 opcode = 0;
3559
3560 if ((opcode || alias_id >= 0) && !flag_mri)
3561 {
3562 char *p = input_line_pointer;
3563
3564 while (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r')
3565 p++;
3566
3567 if (*p != '\n' && *p)
3568 as_bad (_("Garbage at end of instruction: `%s'."), p);
3569 }
3570
3571 input_line_pointer = save;
3572
3573 if (alias_id >= 0)
3574 {
3575 char *f = m68hc11_new_insn (m68hc12_alias[alias_id].size);
fafb6d17 3576
60bcf0fa
NC
3577 number_to_chars_bigendian (f, m68hc12_alias[alias_id].code1, 1);
3578 if (m68hc12_alias[alias_id].size > 1)
3579 number_to_chars_bigendian (f + 1, m68hc12_alias[alias_id].code2, 1);
3580
3581 return;
3582 }
3583
3584 /* Opcode is known but does not have valid operands. Print out the
3585 syntax for this opcode. */
3586 if (opcode == 0)
3587 {
3588 if (flag_print_insn_syntax)
3589 print_insn_format (name);
3590
6927f982
NC
3591 if (((strcmp (name, "movb") == 0) || (strcmp (name, "movw") == 0))
3592 && (current_architecture & cpu9s12x))
3593 {
3594 char *f;
3595 int movb;
3596 if (strcmp (name, "movb") == 0)
3597 movb = 8;
3598 else
3599 movb = 0;
3600
3601 /* The existing operand extract code fell over if these additional modes
3602 were enabled in m68hc11-opc.c. So they are commented there and
3603 decoded here instead. */
3604
3605 if (operands[1].mode & (M6812_OP_IDX | M6812_OP_IDX_1
3606 | M6812_OP_IDX_2 | M6812_OP_D_IDX | M6812_OP_D_IDX_2 | M6812_PRE_INC
3607 | M6812_PRE_DEC | M6812_POST_INC | M6812_POST_DEC ))
3608 {
3609 /* first check if valid mode then start building it up */
3610 if (operands[0].mode & (M6811_OP_IMM8 | M6811_OP_IMM16
3611 | M6811_OP_IND16 | M6812_OP_IDX | M6812_OP_IDX_1
3612 | M6812_OP_IDX_2 | M6812_OP_D_IDX | M6812_OP_D_IDX_2))
3613 {
3614 int opr16a;
3615 if (operands[1].mode & (M6811_OP_IND16))
3616 opr16a = 3;
3617 else
3618 opr16a = 0;
3619
3620 f = m68hc11_new_insn (2);
3621
3622 if (operands[0].mode & (M6811_OP_IMM8 | M6811_OP_IMM16))
3623 {
3624 number_to_chars_bigendian (f, 0x1800 + movb + opr16a, 2);
3625 build_indexed_byte (&operands[1], operands[1].mode, 1);
3626 if (movb)
3627 fixup8 (&operands[0].exp, M6811_OP_IMM8,
3628 operands[0].mode);
3629 else
3630 fixup16 (&operands[0].exp, M6811_OP_IMM16,
3631 operands[0].mode);
3632
3633 return;
3634 }
3635 else if (operands[0].mode & M6811_OP_IND16)
3636 {
3637 number_to_chars_bigendian (f, 0x1801 + movb + opr16a, 2);
3638 build_indexed_byte (&operands[1], operands[1].mode, 1);
3639 fixup16 (&operands[0].exp, M6811_OP_IND16, operands[0].mode);
3640 return;
3641 }
3642 else
3643 {
3644 number_to_chars_bigendian (f, 0x1802 + movb + opr16a, 2);
3645 build_indexed_byte (&operands[0], operands[0].mode, 1);
3646 build_indexed_byte (&operands[1], operands[1].mode, 1);
3647 return;
3648 }
3649 }
3650 }
3651 else if (operands[1].mode & M6811_OP_IND16)
3652 {
3653 /* First check if this is valid mode, then start building it up. */
3654 if (operands[0].mode & (M6811_OP_IMM8 | M6811_OP_IMM16
3655 | M6811_OP_IND16 | M6812_OP_IDX | M6812_OP_IDX_1
3656 | M6812_OP_IDX_2 | M6812_OP_D_IDX | M6812_OP_D_IDX_2))
3657 {
3658 int opr16a;
3659 if (operands[1].mode & (M6811_OP_IND16))
3660 opr16a = 3;
3661 else
3662 opr16a = 0;
3663
3664 f = m68hc11_new_insn (2);
3665
3666 /* The first two cases here should actually be covered by the
3667 normal operand code. */
3668 if (operands[0].mode & (M6811_OP_IMM8 | M6811_OP_IMM16))
3669 {
3670 number_to_chars_bigendian (f, 0x1800 + movb + opr16a, 2);
3671 if (movb)
3672 fixup8 (&operands[0].exp, M6811_OP_IMM8, operands[0].mode);
3673 else
3674 fixup16 (&operands[0].exp, M6811_OP_IMM16, operands[0].mode);
3675
3676 fixup16 (&operands[0].exp, M6811_OP_IND16, operands[0].mode);
3677 return;
3678 }
3679 else if (operands[0].mode & M6811_OP_IND16)
3680 {
3681 number_to_chars_bigendian (f, 0x1801 + movb + opr16a, 2);
3682 build_indexed_byte (&operands[1], operands[1].mode, 1);
3683 fixup16 (&operands[0].exp, M6811_OP_IND16, operands[0].mode);
3684 return;
3685 }
3686 else
3687 {
3688 number_to_chars_bigendian (f, 0x1802 + movb + opr16a, 2);
3689 build_indexed_byte (&operands[0], operands[0].mode, 1);
3690 fixup16 (&operands[1].exp, M6811_OP_IND16, operands[1].mode);
3691 return;
3692 }
3693 }
3694 }
3695
3696 as_bad (_("Invalid operand for `%s'"), name);
3697 return;
3698
3699 }
3700 else
3701 {
3702 as_bad (_("Invalid operand for `%s'"), name);
3703 return;
3704 }
60bcf0fa
NC
3705 }
3706
3707 /* Treat dbeq/ibeq/tbeq instructions in a special way. The branch is
3708 relative and must be in the range -256..255 (9-bits). */
3709 if ((opcode->format & M6812_XBCC_MARKER)
3710 && (opcode->format & M6811_OP_JUMP_REL))
27302d63 3711 build_dbranch_insn (opcode, operands, nb_operands, branch_optimize);
60bcf0fa
NC
3712
3713 /* Relative jumps instructions are taken care of separately. We have to make
3714 sure that the relative branch is within the range -128..127. If it's out
3715 of range, the instructions are changed into absolute instructions.
3716 This is not supported for the brset and brclr instructions. */
3717 else if ((opcode->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
3718 && !(opcode->format & M6811_OP_BITMASK))
3719 build_jump_insn (opcode, operands, nb_operands, branch_optimize);
3720 else
3721 build_insn (opcode, operands, nb_operands);
3722}
eb086b59
SC
3723
3724\f
3725/* Pseudo op to control the ELF flags. */
3726static void
ca43c854 3727s_m68hc11_mode (int x ATTRIBUTE_UNUSED)
eb086b59
SC
3728{
3729 char *name = input_line_pointer, ch;
3730
3731 while (!is_end_of_line[(unsigned char) *input_line_pointer])
3732 input_line_pointer++;
3733 ch = *input_line_pointer;
3734 *input_line_pointer = '\0';
3735
3736 if (strcmp (name, "mshort") == 0)
3737 {
3738 elf_flags &= ~E_M68HC11_I32;
3739 }
3740 else if (strcmp (name, "mlong") == 0)
3741 {
3742 elf_flags |= E_M68HC11_I32;
3743 }
3744 else if (strcmp (name, "mshort-double") == 0)
3745 {
3746 elf_flags &= ~E_M68HC11_F64;
3747 }
3748 else if (strcmp (name, "mlong-double") == 0)
3749 {
3750 elf_flags |= E_M68HC11_F64;
3751 }
3752 else
3753 {
3754 as_warn (_("Invalid mode: %s\n"), name);
3755 }
3756 *input_line_pointer = ch;
3757 demand_empty_rest_of_line ();
3758}
3759
3760/* Mark the symbols with STO_M68HC12_FAR to indicate the functions
3761 are using 'rtc' for returning. It is necessary to use 'call'
3762 to invoke them. This is also used by the debugger to correctly
3763 find the stack frame. */
3764static void
ca43c854 3765s_m68hc11_mark_symbol (int mark)
eb086b59
SC
3766{
3767 char *name;
3768 int c;
3769 symbolS *symbolP;
3770 asymbol *bfdsym;
3771 elf_symbol_type *elfsym;
3772
3773 do
3774 {
3775 name = input_line_pointer;
3776 c = get_symbol_end ();
3777 symbolP = symbol_find_or_make (name);
3778 *input_line_pointer = c;
3779
3780 SKIP_WHITESPACE ();
3781
3782 bfdsym = symbol_get_bfdsym (symbolP);
3783 elfsym = elf_symbol_from (bfd_asymbol_bfd (bfdsym), bfdsym);
3784
9c2799c2 3785 gas_assert (elfsym);
eb086b59
SC
3786
3787 /* Mark the symbol far (using rtc for function return). */
3788 elfsym->internal_elf_sym.st_other |= mark;
3789
3790 if (c == ',')
3791 {
3792 input_line_pointer ++;
3793
3794 SKIP_WHITESPACE ();
3795
3796 if (*input_line_pointer == '\n')
3797 c = '\n';
3798 }
3799 }
3800 while (c == ',');
3801
3802 demand_empty_rest_of_line ();
3803}
e371935f
SC
3804
3805static void
ca43c854 3806s_m68hc11_relax (int ignore ATTRIBUTE_UNUSED)
e371935f
SC
3807{
3808 expressionS ex;
3809
3810 expression (&ex);
3811
3812 if (ex.X_op != O_symbol || ex.X_add_number != 0)
3813 {
3814 as_bad (_("bad .relax format"));
3815 ignore_rest_of_line ();
3816 return;
3817 }
3818
fd99afa7 3819 fix_new_exp (frag_now, frag_now_fix (), 0, &ex, 1,
e371935f
SC
3820 BFD_RELOC_M68HC11_RL_GROUP);
3821
3822 demand_empty_rest_of_line ();
3823}
3824
60bcf0fa
NC
3825\f
3826/* Relocation, relaxation and frag conversions. */
e371935f
SC
3827
3828/* PC-relative offsets are relative to the start of the
3829 next instruction. That is, the address of the offset, plus its
3830 size, since the offset is always the last part of the insn. */
60bcf0fa 3831long
ca43c854 3832md_pcrel_from (fixS *fixP)
60bcf0fa 3833{
e371935f 3834 if (fixP->fx_r_type == BFD_RELOC_M68HC11_RL_JUMP)
60bcf0fa
NC
3835 return 0;
3836
e371935f 3837 return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
60bcf0fa
NC
3838}
3839
3840/* If while processing a fixup, a reloc really needs to be created
3841 then it is done here. */
3842arelent *
ca43c854 3843tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
60bcf0fa
NC
3844{
3845 arelent *reloc;
3846
3847 reloc = (arelent *) xmalloc (sizeof (arelent));
3848 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
3849 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
3850 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
3851 if (fixp->fx_r_type == 0)
3852 reloc->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_16);
3853 else
3854 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
3855 if (reloc->howto == (reloc_howto_type *) NULL)
3856 {
3857 as_bad_where (fixp->fx_file, fixp->fx_line,
3858 _("Relocation %d is not supported by object file format."),
3859 (int) fixp->fx_r_type);
3860 return NULL;
3861 }
3862
a161fe53
AM
3863 /* Since we use Rel instead of Rela, encode the vtable entry to be
3864 used in the relocation's section offset. */
3865 if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
3866 reloc->address = fixp->fx_offset;
3867
3868 reloc->addend = 0;
60bcf0fa
NC
3869 return reloc;
3870}
3871
c9e03e8b
SC
3872/* We need a port-specific relaxation function to cope with sym2 - sym1
3873 relative expressions with both symbols in the same segment (but not
3874 necessarily in the same frag as this insn), for example:
3875 ldab sym2-(sym1-2),pc
3876 sym1:
3877 The offset can be 5, 9 or 16 bits long. */
3878
3879long
ca43c854
SC
3880m68hc11_relax_frag (segT seg ATTRIBUTE_UNUSED, fragS *fragP,
3881 long stretch ATTRIBUTE_UNUSED)
c9e03e8b
SC
3882{
3883 long growth;
3884 offsetT aim = 0;
3885 symbolS *symbolP;
3886 const relax_typeS *this_type;
3887 const relax_typeS *start_type;
3888 relax_substateT next_state;
3889 relax_substateT this_state;
3890 const relax_typeS *table = TC_GENERIC_RELAX_TABLE;
3891
3892 /* We only have to cope with frags as prepared by
3893 md_estimate_size_before_relax. The STATE_BITS16 case may geet here
3894 because of the different reasons that it's not relaxable. */
3895 switch (fragP->fr_subtype)
3896 {
75538612 3897 case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS16):
c9e03e8b
SC
3898 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16):
3899 /* When we get to this state, the frag won't grow any more. */
3900 return 0;
3901
75538612 3902 case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS5):
c9e03e8b 3903 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS5):
75538612 3904 case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS9):
c9e03e8b
SC
3905 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9):
3906 if (fragP->fr_symbol == NULL
3907 || S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
3908 as_fatal (_("internal inconsistency problem in %s: fr_symbol %lx"),
3909 __FUNCTION__, (long) fragP->fr_symbol);
3910 symbolP = fragP->fr_symbol;
3911 if (symbol_resolved_p (symbolP))
3912 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
3913 __FUNCTION__);
3914 aim = S_GET_VALUE (symbolP);
3915 break;
3916
3917 default:
3918 as_fatal (_("internal inconsistency problem in %s: fr_subtype %d"),
3919 __FUNCTION__, fragP->fr_subtype);
3920 }
3921
3922 /* The rest is stolen from relax_frag. There's no obvious way to
3923 share the code, but fortunately no requirement to keep in sync as
3924 long as fragP->fr_symbol does not have its segment changed. */
3925
3926 this_state = fragP->fr_subtype;
3927 start_type = this_type = table + this_state;
3928
3929 if (aim < 0)
3930 {
3931 /* Look backwards. */
3932 for (next_state = this_type->rlx_more; next_state;)
3933 if (aim >= this_type->rlx_backward)
3934 next_state = 0;
3935 else
3936 {
3937 /* Grow to next state. */
3938 this_state = next_state;
3939 this_type = table + this_state;
3940 next_state = this_type->rlx_more;
3941 }
3942 }
3943 else
3944 {
3945 /* Look forwards. */
3946 for (next_state = this_type->rlx_more; next_state;)
3947 if (aim <= this_type->rlx_forward)
3948 next_state = 0;
3949 else
3950 {
3951 /* Grow to next state. */
3952 this_state = next_state;
3953 this_type = table + this_state;
3954 next_state = this_type->rlx_more;
3955 }
3956 }
3957
3958 growth = this_type->rlx_length - start_type->rlx_length;
3959 if (growth != 0)
3960 fragP->fr_subtype = this_state;
3961 return growth;
3962}
3963
60bcf0fa 3964void
ca43c854
SC
3965md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, asection *sec ATTRIBUTE_UNUSED,
3966 fragS *fragP)
60bcf0fa
NC
3967{
3968 fixS *fixp;
88051039 3969 long value;
60bcf0fa
NC
3970 long disp;
3971 char *buffer_address = fragP->fr_literal;
3972
3973 /* Address in object code of the displacement. */
3974 register int object_address = fragP->fr_fix + fragP->fr_address;
3975
3976 buffer_address += fragP->fr_fix;
3977
3978 /* The displacement of the address, from current location. */
ac62c346 3979 value = S_GET_VALUE (fragP->fr_symbol);
88051039 3980 disp = (value + fragP->fr_offset) - object_address;
60bcf0fa
NC
3981
3982 switch (fragP->fr_subtype)
3983 {
3984 case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE):
3985 fragP->fr_opcode[1] = disp;
3986 break;
3987
3988 case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD):
3989 /* This relax is only for bsr and bra. */
9c2799c2 3990 gas_assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
60bcf0fa
NC
3991 || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
3992 || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
3993
3994 fragP->fr_opcode[0] = convert_branch (fragP->fr_opcode[0]);
3995
3996 fix_new (fragP, fragP->fr_fix - 1, 2,
3997 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
3998 fragP->fr_fix += 1;
3999 break;
4000
4001 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_BYTE):
4002 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_BYTE):
4003 fragP->fr_opcode[1] = disp;
4004 break;
4005
4006 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_WORD):
4007 /* Invert branch. */
4008 fragP->fr_opcode[0] ^= 1;
fafb6d17 4009 fragP->fr_opcode[1] = 3; /* Branch offset. */
60bcf0fa
NC
4010 buffer_address[0] = M6811_JMP;
4011 fix_new (fragP, fragP->fr_fix + 1, 2,
4012 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
4013 fragP->fr_fix += 3;
4014 break;
4015
4016 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_WORD):
4017 /* Translate branch into a long branch. */
4018 fragP->fr_opcode[1] = fragP->fr_opcode[0];
4019 fragP->fr_opcode[0] = M6811_OPCODE_PAGE2;
4020
4021 fixp = fix_new (fragP, fragP->fr_fix, 2,
4022 fragP->fr_symbol, fragP->fr_offset, 1,
4023 BFD_RELOC_16_PCREL);
4024 fixp->fx_pcrel_adjust = 2;
4025 fragP->fr_fix += 2;
4026 break;
4027
75538612
SC
4028 case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS5):
4029 if (fragP->fr_symbol != 0
c9e03e8b
SC
4030 && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
4031 value = disp;
75538612
SC
4032 /* fall through */
4033
4034 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS5):
88051039 4035 fragP->fr_opcode[0] = fragP->fr_opcode[0] << 6;
c9e03e8b 4036 fragP->fr_opcode[0] |= value & 0x1f;
60bcf0fa
NC
4037 break;
4038
75538612
SC
4039 case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS9):
4040 /* For a PC-relative offset, use the displacement with a -1 correction
4041 to take into account the additional byte of the insn. */
4042 if (fragP->fr_symbol != 0
c9e03e8b 4043 && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
75538612
SC
4044 value = disp - 1;
4045 /* fall through */
4046
4047 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9):
60bcf0fa
NC
4048 fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3);
4049 fragP->fr_opcode[0] |= 0xE0;
c9e03e8b
SC
4050 fragP->fr_opcode[0] |= (value >> 8) & 1;
4051 fragP->fr_opcode[1] = value;
60bcf0fa
NC
4052 fragP->fr_fix += 1;
4053 break;
4054
75538612 4055 case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS16):
60bcf0fa
NC
4056 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16):
4057 fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3);
88051039 4058 fragP->fr_opcode[0] |= 0xe2;
c9e03e8b
SC
4059 if ((fragP->fr_opcode[0] & 0x0ff) == 0x0fa
4060 && fragP->fr_symbol != 0
4061 && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
098f2ec3
KH
4062 {
4063 fixp = fix_new (fragP, fragP->fr_fix, 2,
4064 fragP->fr_symbol, fragP->fr_offset,
4065 1, BFD_RELOC_16_PCREL);
098f2ec3 4066 }
88051039 4067 else
098f2ec3
KH
4068 {
4069 fix_new (fragP, fragP->fr_fix, 2,
4070 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
4071 }
88051039 4072 fragP->fr_fix += 2;
60bcf0fa
NC
4073 break;
4074
4075 case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_BYTE):
4076 if (disp < 0)
4077 fragP->fr_opcode[0] |= 0x10;
4078
4079 fragP->fr_opcode[1] = disp & 0x0FF;
4080 break;
4081
4082 case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_WORD):
4083 /* Invert branch. */
4084 fragP->fr_opcode[0] ^= 0x20;
4085 fragP->fr_opcode[1] = 3; /* Branch offset. */
4086 buffer_address[0] = M6812_JMP;
4087 fix_new (fragP, fragP->fr_fix + 1, 2,
4088 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
4089 fragP->fr_fix += 3;
4090 break;
4091
4092 default:
4093 break;
4094 }
4095}
4096
dbb8ad49
SC
4097/* On an ELF system, we can't relax a weak symbol. The weak symbol
4098 can be overridden at final link time by a non weak symbol. We can
4099 relax externally visible symbol because there is no shared library
4100 and such symbol can't be overridden (unless they are weak). */
d8273f3b 4101static int
ca43c854 4102relaxable_symbol (symbolS *symbol)
d8273f3b 4103{
dbb8ad49 4104 return ! S_IS_WEAK (symbol);
d8273f3b
SC
4105}
4106
60bcf0fa
NC
4107/* Force truly undefined symbols to their maximum size, and generally set up
4108 the frag list to be relaxed. */
4109int
ca43c854 4110md_estimate_size_before_relax (fragS *fragP, asection *segment)
60bcf0fa 4111{
606ab118
AM
4112 if (RELAX_LENGTH (fragP->fr_subtype) == STATE_UNDF)
4113 {
4114 if (S_GET_SEGMENT (fragP->fr_symbol) != segment
577300ce
SC
4115 || !relaxable_symbol (fragP->fr_symbol)
4116 || (segment != absolute_section
4117 && RELAX_STATE (fragP->fr_subtype) == STATE_INDEXED_OFFSET))
606ab118
AM
4118 {
4119 /* Non-relaxable cases. */
4120 int old_fr_fix;
4121 char *buffer_address;
60bcf0fa 4122
606ab118
AM
4123 old_fr_fix = fragP->fr_fix;
4124 buffer_address = fragP->fr_fix + fragP->fr_literal;
60bcf0fa 4125
606ab118
AM
4126 switch (RELAX_STATE (fragP->fr_subtype))
4127 {
4128 case STATE_PC_RELATIVE:
4129
4130 /* This relax is only for bsr and bra. */
9c2799c2 4131 gas_assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
606ab118
AM
4132 || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
4133 || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
4134
1370e33d 4135 if (flag_fixed_branches)
606ab118
AM
4136 as_bad_where (fragP->fr_file, fragP->fr_line,
4137 _("bra or bsr with undefined symbol."));
4138
4139 /* The symbol is undefined or in a separate section.
4140 Turn bra into a jmp and bsr into a jsr. The insn
4141 becomes 3 bytes long (instead of 2). A fixup is
4142 necessary for the unresolved symbol address. */
4143 fragP->fr_opcode[0] = convert_branch (fragP->fr_opcode[0]);
4144
13283e2d 4145 fix_new (fragP, fragP->fr_fix - 1, 2, fragP->fr_symbol,
606ab118 4146 fragP->fr_offset, 0, BFD_RELOC_16);
13283e2d 4147 fragP->fr_fix++;
606ab118 4148 break;
60bcf0fa 4149
606ab118 4150 case STATE_CONDITIONAL_BRANCH:
9c2799c2 4151 gas_assert (current_architecture & cpu6811);
60bcf0fa 4152
606ab118
AM
4153 fragP->fr_opcode[0] ^= 1; /* Reverse sense of branch. */
4154 fragP->fr_opcode[1] = 3; /* Skip next jmp insn (3 bytes). */
60bcf0fa 4155
606ab118
AM
4156 /* Don't use fr_opcode[2] because this may be
4157 in a different frag. */
4158 buffer_address[0] = M6811_JMP;
60bcf0fa 4159
606ab118
AM
4160 fragP->fr_fix++;
4161 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
4162 fragP->fr_offset, 0, BFD_RELOC_16);
4163 fragP->fr_fix += 2;
4164 break;
60bcf0fa 4165
606ab118 4166 case STATE_INDEXED_OFFSET:
9c2799c2 4167 gas_assert (current_architecture & cpu6812);
60bcf0fa 4168
c9e03e8b
SC
4169 if (fragP->fr_symbol
4170 && S_GET_SEGMENT (fragP->fr_symbol) == absolute_section)
4171 {
4172 fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_OFFSET,
4173 STATE_BITS5);
4174 /* Return the size of the variable part of the frag. */
4175 return md_relax_table[fragP->fr_subtype].rlx_length;
4176 }
4177 else
4178 {
4179 /* Switch the indexed operation to 16-bit mode. */
4180 fragP->fr_opcode[0] = fragP->fr_opcode[0] << 3;
4181 fragP->fr_opcode[0] |= 0xe2;
4182 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
4183 fragP->fr_offset, 0, BFD_RELOC_16);
4184 fragP->fr_fix += 2;
4185 }
606ab118 4186 break;
60bcf0fa 4187
75538612 4188 case STATE_INDEXED_PCREL:
9c2799c2 4189 gas_assert (current_architecture & cpu6812);
75538612
SC
4190
4191 if (fragP->fr_symbol
4192 && S_GET_SEGMENT (fragP->fr_symbol) == absolute_section)
4193 {
4194 fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_PCREL,
4195 STATE_BITS5);
4196 /* Return the size of the variable part of the frag. */
4197 return md_relax_table[fragP->fr_subtype].rlx_length;
4198 }
4199 else
4200 {
75538612
SC
4201 fragP->fr_opcode[0] = fragP->fr_opcode[0] << 3;
4202 fragP->fr_opcode[0] |= 0xe2;
87975d2a
AM
4203 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
4204 fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
75538612
SC
4205 fragP->fr_fix += 2;
4206 }
4207 break;
4208
606ab118 4209 case STATE_XBCC_BRANCH:
9c2799c2 4210 gas_assert (current_architecture & cpu6812);
606ab118
AM
4211
4212 fragP->fr_opcode[0] ^= 0x20; /* Reverse sense of branch. */
4213 fragP->fr_opcode[1] = 3; /* Skip next jmp insn (3 bytes). */
60bcf0fa 4214
606ab118
AM
4215 /* Don't use fr_opcode[2] because this may be
4216 in a different frag. */
4217 buffer_address[0] = M6812_JMP;
4218
4219 fragP->fr_fix++;
4220 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
4221 fragP->fr_offset, 0, BFD_RELOC_16);
4222 fragP->fr_fix += 2;
4223 break;
60bcf0fa 4224
606ab118 4225 case STATE_CONDITIONAL_BRANCH_6812:
9c2799c2 4226 gas_assert (current_architecture & cpu6812);
606ab118
AM
4227
4228 /* Translate into a lbcc branch. */
4229 fragP->fr_opcode[1] = fragP->fr_opcode[0];
4230 fragP->fr_opcode[0] = M6811_OPCODE_PAGE2;
4231
4232 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
e371935f 4233 fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
606ab118
AM
4234 fragP->fr_fix += 2;
4235 break;
4236
4237 default:
4238 as_fatal (_("Subtype %d is not recognized."), fragP->fr_subtype);
4239 }
60bcf0fa 4240 frag_wane (fragP);
60bcf0fa 4241
606ab118
AM
4242 /* Return the growth in the fixed part of the frag. */
4243 return fragP->fr_fix - old_fr_fix;
4244 }
60bcf0fa 4245
606ab118
AM
4246 /* Relaxable cases. */
4247 switch (RELAX_STATE (fragP->fr_subtype))
60bcf0fa 4248 {
606ab118
AM
4249 case STATE_PC_RELATIVE:
4250 /* This relax is only for bsr and bra. */
9c2799c2 4251 gas_assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
606ab118
AM
4252 || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
4253 || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
4254
4255 fragP->fr_subtype = ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE);
4256 break;
4257
4258 case STATE_CONDITIONAL_BRANCH:
9c2799c2 4259 gas_assert (current_architecture & cpu6811);
606ab118
AM
4260
4261 fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH,
4262 STATE_BYTE);
4263 break;
4264
4265 case STATE_INDEXED_OFFSET:
9c2799c2 4266 gas_assert (current_architecture & cpu6812);
606ab118 4267
60bcf0fa
NC
4268 fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_OFFSET,
4269 STATE_BITS5);
606ab118 4270 break;
60bcf0fa 4271
75538612 4272 case STATE_INDEXED_PCREL:
9c2799c2 4273 gas_assert (current_architecture & cpu6812);
75538612
SC
4274
4275 fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_PCREL,
4276 STATE_BITS5);
4277 break;
4278
606ab118 4279 case STATE_XBCC_BRANCH:
9c2799c2 4280 gas_assert (current_architecture & cpu6812);
60bcf0fa 4281
60bcf0fa 4282 fragP->fr_subtype = ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_BYTE);
606ab118 4283 break;
60bcf0fa 4284
606ab118 4285 case STATE_CONDITIONAL_BRANCH_6812:
9c2799c2 4286 gas_assert (current_architecture & cpu6812);
60bcf0fa 4287
60bcf0fa
NC
4288 fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812,
4289 STATE_BYTE);
606ab118 4290 break;
60bcf0fa 4291 }
60bcf0fa
NC
4292 }
4293
606ab118
AM
4294 if (fragP->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))
4295 as_fatal (_("Subtype %d is not recognized."), fragP->fr_subtype);
4296
4297 /* Return the size of the variable part of the frag. */
4298 return md_relax_table[fragP->fr_subtype].rlx_length;
60bcf0fa
NC
4299}
4300
e371935f
SC
4301/* See whether we need to force a relocation into the output file. */
4302int
ca43c854 4303tc_m68hc11_force_relocation (fixS *fixP)
e371935f 4304{
ae6063d4
AM
4305 if (fixP->fx_r_type == BFD_RELOC_M68HC11_RL_GROUP)
4306 return 1;
a161fe53 4307
ae6063d4 4308 return generic_force_reloc (fixP);
e371935f
SC
4309}
4310
4311/* Here we decide which fixups can be adjusted to make them relative
4312 to the beginning of the section instead of the symbol. Basically
4313 we need to make sure that the linker relaxation is done
4314 correctly, so in some cases we force the original symbol to be
4315 used. */
4316int
ca43c854 4317tc_m68hc11_fix_adjustable (fixS *fixP)
e371935f 4318{
e371935f
SC
4319 switch (fixP->fx_r_type)
4320 {
4321 /* For the linker relaxation to work correctly, these relocs
4322 need to be on the symbol itself. */
4323 case BFD_RELOC_16:
e371935f
SC
4324 case BFD_RELOC_M68HC11_RL_JUMP:
4325 case BFD_RELOC_M68HC11_RL_GROUP:
4326 case BFD_RELOC_VTABLE_INHERIT:
4327 case BFD_RELOC_VTABLE_ENTRY:
577300ce 4328 case BFD_RELOC_32:
2d94a61a
SC
4329
4330 /* The memory bank addressing translation also needs the original
4331 symbol. */
577300ce 4332 case BFD_RELOC_M68HC11_LO16:
2d94a61a
SC
4333 case BFD_RELOC_M68HC11_PAGE:
4334 case BFD_RELOC_M68HC11_24:
e371935f
SC
4335 return 0;
4336
e371935f
SC
4337 default:
4338 return 1;
4339 }
4340}
4341
94f592af 4342void
55cf6793 4343md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
60bcf0fa
NC
4344{
4345 char *where;
94f592af 4346 long value = * valP;
60bcf0fa 4347
94f592af
NC
4348 if (fixP->fx_addsy == (symbolS *) NULL)
4349 fixP->fx_done = 1;
4350
a161fe53
AM
4351 /* We don't actually support subtracting a symbol. */
4352 if (fixP->fx_subsy != (symbolS *) NULL)
4353 as_bad_where (fixP->fx_file, fixP->fx_line, _("Expression too complex."));
60bcf0fa 4354
60bcf0fa
NC
4355 /* Patch the instruction with the resolved operand. Elf relocation
4356 info will also be generated to take care of linker/loader fixups.
4357 The 68HC11 addresses only 64Kb, we are only concerned by 8 and 16-bit
4358 relocs. BFD_RELOC_8 is basically used for .page0 access (the linker
4359 will warn for overflows). BFD_RELOC_8_PCREL should not be generated
4360 because it's either resolved or turned out into non-relative insns (see
4361 relax table, bcc, bra, bsr transformations)
4362
4363 The BFD_RELOC_32 is necessary for the support of --gstabs. */
94f592af 4364 where = fixP->fx_frag->fr_literal + fixP->fx_where;
60bcf0fa 4365
94f592af 4366 switch (fixP->fx_r_type)
60bcf0fa
NC
4367 {
4368 case BFD_RELOC_32:
4369 bfd_putb32 ((bfd_vma) value, (unsigned char *) where);
4370 break;
4371
7bfda7eb
SC
4372 case BFD_RELOC_24:
4373 case BFD_RELOC_M68HC11_24:
4374 bfd_putb16 ((bfd_vma) (value & 0x0ffff), (unsigned char *) where);
4375 ((bfd_byte*) where)[2] = ((value >> 16) & 0x0ff);
4376 break;
4377
60bcf0fa
NC
4378 case BFD_RELOC_16:
4379 case BFD_RELOC_16_PCREL:
7bfda7eb 4380 case BFD_RELOC_M68HC11_LO16:
60bcf0fa
NC
4381 bfd_putb16 ((bfd_vma) value, (unsigned char *) where);
4382 if (value < -65537 || value > 65535)
94f592af 4383 as_bad_where (fixP->fx_file, fixP->fx_line,
60bcf0fa
NC
4384 _("Value out of 16-bit range."));
4385 break;
4386
4387 case BFD_RELOC_M68HC11_HI8:
6927f982
NC
4388 /* Caution, %hi(<symbol>+%ld) will generate incorrect code if %lo
4389 causes a carry. */
4390 case BFD_RELOC_M68HC12_HI8XG:
60bcf0fa 4391 value = value >> 8;
fafb6d17 4392 /* Fall through. */
60bcf0fa 4393
6927f982 4394 case BFD_RELOC_M68HC12_LO8XG:
60bcf0fa
NC
4395 case BFD_RELOC_M68HC11_LO8:
4396 case BFD_RELOC_8:
7bfda7eb 4397 case BFD_RELOC_M68HC11_PAGE:
60bcf0fa
NC
4398 ((bfd_byte *) where)[0] = (bfd_byte) value;
4399 break;
4400
4401 case BFD_RELOC_8_PCREL:
60bcf0fa
NC
4402 ((bfd_byte *) where)[0] = (bfd_byte) value;
4403
4404 if (value < -128 || value > 127)
94f592af 4405 as_bad_where (fixP->fx_file, fixP->fx_line,
60bcf0fa
NC
4406 _("Value %ld too large for 8-bit PC-relative branch."),
4407 value);
4408 break;
4409
6927f982
NC
4410 /* These next two are for XGATE. */
4411 case BFD_RELOC_M68HC12_9_PCREL:
4412 ((bfd_byte *) where)[0] |= (bfd_byte) ((value >>9) & 0x01);
4413 ((bfd_byte *) where)[1] = (bfd_byte) ((value>>1) & 0xff);
4414 if (value < -512 || value > 511)
4415 as_bad_where (fixP->fx_file, fixP->fx_line,
4416 _("Value %ld too large for 9-bit PC-relative branch."),
4417 value);
4418 break;
4419
4420 case BFD_RELOC_M68HC12_10_PCREL:
4421 ((bfd_byte *) where)[0] |= (bfd_byte) ((value >>9) & 0x03);
4422 ((bfd_byte *) where)[1] = (bfd_byte) ((value>>1) & 0xff);
4423 if (value < -1024 || value > 1023)
4424 as_bad_where (fixP->fx_file, fixP->fx_line,
4425 _("Value %ld too large for 10-bit PC-relative branch."),
4426 value);
4427
4428 break;
4429
60bcf0fa
NC
4430 case BFD_RELOC_M68HC11_3B:
4431 if (value <= 0 || value > 8)
94f592af 4432 as_bad_where (fixP->fx_file, fixP->fx_line,
60bcf0fa
NC
4433 _("Auto increment/decrement offset '%ld' is out of range."),
4434 value);
4435 if (where[0] & 0x8)
4436 value = 8 - value;
4437 else
4438 value--;
4439
4440 where[0] = where[0] | (value & 0x07);
4441 break;
4442
28d39d1a
NC
4443 case BFD_RELOC_M68HC12_5B:
4444 if (value < -16 || value > 15)
4445 as_bad_where (fixP->fx_file, fixP->fx_line,
4446 _("Offset out of 5-bit range for movw/movb insn: %ld"),
4447 value);
4448 if (value >= 0)
4449 where[0] |= value;
4450 else
4451 where[0] |= (0x10 | (16 + value));
4452 break;
4453
6927f982
NC
4454 case BFD_RELOC_M68HC12_9B:
4455 if (value < -256 || value > 255)
4456 as_bad_where (fixP->fx_file, fixP->fx_line,
4457 _("Offset out of 9-bit range for movw/movb insn: %ld"),
4458 value);
4459 /* sign bit already in xb postbyte */
4460 if (value >= 0)
4461 where[1] = value;
4462 else
4463 where[1] = (256 + value);
4464 break;
4465
4466 case BFD_RELOC_M68HC12_16B:
4467 if (value < -32768 || value > 32767)
4468 as_bad_where (fixP->fx_file, fixP->fx_line,
4469 _("Offset out of 16-bit range for movw/movb insn: %ld"),
4470 value);
4471 if (value < 0)
4472 value += 65536;
4473
4474 where[1] = (value >> 8);
4475 where[2] = (value & 0xff);
4476 break;
4477
e371935f
SC
4478 case BFD_RELOC_M68HC11_RL_JUMP:
4479 case BFD_RELOC_M68HC11_RL_GROUP:
4480 case BFD_RELOC_VTABLE_INHERIT:
4481 case BFD_RELOC_VTABLE_ENTRY:
4482 fixP->fx_done = 0;
4483 return;
4484
60bcf0fa
NC
4485 default:
4486 as_fatal (_("Line %d: unknown relocation type: 0x%x."),
94f592af 4487 fixP->fx_line, fixP->fx_r_type);
60bcf0fa 4488 }
60bcf0fa 4489}
eb086b59
SC
4490
4491/* Set the ELF specific flags. */
4492void
ca43c854 4493m68hc11_elf_final_processing (void)
eb086b59 4494{
d01030e6
SC
4495 if (current_architecture & cpu6812s)
4496 elf_flags |= EF_M68HCS12_MACH;
eb086b59
SC
4497 elf_elfheader (stdoutput)->e_flags &= ~EF_M68HC11_ABI;
4498 elf_elfheader (stdoutput)->e_flags |= elf_flags;
4499}
bdfd67fa
SK
4500
4501/* Process directives specified via pseudo ops */
4502static void
4503s_m68hc11_parse_pseudo_instruction (int pseudo_insn)
4504{
4505 switch (pseudo_insn)
4506 {
4507 case E_M68HC11_NO_BANK_WARNING:
4508 elf_flags |= E_M68HC11_NO_BANK_WARNING;
4509 break;
4510 default:
4511 as_bad (_("Invalid directive"));
4512 }
4513}
This page took 0.744207 seconds and 4 git commands to generate.