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