source: trunk/binutils/gas/config/tc-m68hc11.c@ 2562

Last change on this file since 2562 was 610, checked in by bird, 22 years ago

This commit was generated by cvs2svn to compensate for changes in r609,
which included commits to RCS files with non-trunk default branches.

  • Property cvs2svn:cvs-rev set to 1.1.1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 88.5 KB
Line 
1/* tc-m68hc11.c -- Assembler code for the Motorola 68HC11 & 68HC12.
2 Copyright 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
3 Written by Stephane Carrez (stcarrez@nerim.fr)
4
5 This file is part of GAS, the GNU Assembler.
6
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
21
22#include "as.h"
23#include "safe-ctype.h"
24#include "subsegs.h"
25#include "opcode/m68hc11.h"
26#include "dwarf2dbg.h"
27#include "elf/m68hc11.h"
28
29const char comment_chars[] = ";!";
30const char line_comment_chars[] = "#*";
31const char line_separator_chars[] = "";
32
33const char EXP_CHARS[] = "eE";
34const char FLT_CHARS[] = "dD";
35
36#define STATE_CONDITIONAL_BRANCH (1)
37#define STATE_PC_RELATIVE (2)
38#define STATE_INDEXED_OFFSET (3)
39#define STATE_INDEXED_PCREL (4)
40#define STATE_XBCC_BRANCH (5)
41#define STATE_CONDITIONAL_BRANCH_6812 (6)
42
43#define STATE_BYTE (0)
44#define STATE_BITS5 (0)
45#define STATE_WORD (1)
46#define STATE_BITS9 (1)
47#define STATE_LONG (2)
48#define STATE_BITS16 (2)
49#define STATE_UNDF (3) /* Symbol undefined in pass1 */
50
51/* This macro has no side-effects. */
52#define ENCODE_RELAX(what,length) (((what) << 2) + (length))
53#define RELAX_STATE(s) ((s) >> 2)
54#define RELAX_LENGTH(s) ((s) & 3)
55
56#define IS_OPCODE(C1,C2) (((C1) & 0x0FF) == ((C2) & 0x0FF))
57
58/* This table describes how you change sizes for the various types of variable
59 size expressions. This version only supports two kinds. */
60
61/* The fields are:
62 How far Forward this mode will reach.
63 How far Backward this mode will reach.
64 How many bytes this mode will add to the size of the frag.
65 Which mode to go to if the offset won't fit in this one. */
66
67relax_typeS md_relax_table[] = {
68 {1, 1, 0, 0}, /* First entries aren't used. */
69 {1, 1, 0, 0}, /* For no good reason except. */
70 {1, 1, 0, 0}, /* that the VAX doesn't either. */
71 {1, 1, 0, 0},
72
73 /* Relax for bcc <L>.
74 These insns are translated into b!cc +3 jmp L. */
75 {(127), (-128), 0, ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_WORD)},
76 {0, 0, 3, 0},
77 {1, 1, 0, 0},
78 {1, 1, 0, 0},
79
80 /* Relax for bsr <L> and bra <L>.
81 These insns are translated into jsr and jmp. */
82 {(127), (-128), 0, ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD)},
83 {0, 0, 1, 0},
84 {1, 1, 0, 0},
85 {1, 1, 0, 0},
86
87 /* Relax for indexed offset: 5-bits, 9-bits, 16-bits. */
88 {(15), (-16), 0, ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9)},
89 {(255), (-256), 1, ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16)},
90 {0, 0, 2, 0},
91 {1, 1, 0, 0},
92
93 /* Relax for PC relative offset: 5-bits, 9-bits, 16-bits.
94 For the 9-bit case, there will be a -1 correction to take into
95 account the new byte that's why the range is -255..256. */
96 {(15), (-16), 0, ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS9)},
97 {(256), (-255), 1, ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS16)},
98 {0, 0, 2, 0},
99 {1, 1, 0, 0},
100
101 /* Relax for dbeq/ibeq/tbeq r,<L>:
102 These insns are translated into db!cc +3 jmp L. */
103 {(255), (-256), 0, ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_WORD)},
104 {0, 0, 3, 0},
105 {1, 1, 0, 0},
106 {1, 1, 0, 0},
107
108 /* Relax for bcc <L> on 68HC12.
109 These insns are translated into lbcc <L>. */
110 {(127), (-128), 0, ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_WORD)},
111 {0, 0, 2, 0},
112 {1, 1, 0, 0},
113 {1, 1, 0, 0},
114
115};
116
117/* 68HC11 and 68HC12 registers. They are numbered according to the 68HC12. */
118typedef enum register_id {
119 REG_NONE = -1,
120 REG_A = 0,
121 REG_B = 1,
122 REG_CCR = 2,
123 REG_D = 4,
124 REG_X = 5,
125 REG_Y = 6,
126 REG_SP = 7,
127 REG_PC = 8
128} register_id;
129
130typedef struct operand {
131 expressionS exp;
132 register_id reg1;
133 register_id reg2;
134 int mode;
135} operand;
136
137struct m68hc11_opcode_def {
138 long format;
139 int min_operands;
140 int max_operands;
141 int nb_modes;
142 int used;
143 struct m68hc11_opcode *opcode;
144};
145
146static struct m68hc11_opcode_def *m68hc11_opcode_defs = 0;
147static int m68hc11_nb_opcode_defs = 0;
148
149typedef struct alias {
150 const char *name;
151 const char *alias;
152} alias;
153
154static alias alias_opcodes[] = {
155 {"cpd", "cmpd"},
156 {"cpx", "cmpx"},
157 {"cpy", "cmpy"},
158 {0, 0}
159};
160
161/* Local functions. */
162static register_id reg_name_search PARAMS ((char *));
163static register_id register_name PARAMS ((void));
164static int cmp_opcode PARAMS ((struct m68hc11_opcode *,
165 struct m68hc11_opcode *));
166static char *print_opcode_format PARAMS ((struct m68hc11_opcode *, int));
167static char *skip_whites PARAMS ((char *));
168static int check_range PARAMS ((long, int));
169static void print_opcode_list PARAMS ((void));
170static void get_default_target PARAMS ((void));
171static void print_insn_format PARAMS ((char *));
172static int get_operand PARAMS ((operand *, int, long));
173static void fixup8 PARAMS ((expressionS *, int, int));
174static void fixup16 PARAMS ((expressionS *, int, int));
175static void fixup24 PARAMS ((expressionS *, int, int));
176static unsigned char convert_branch PARAMS ((unsigned char));
177static char *m68hc11_new_insn PARAMS ((int));
178static void build_dbranch_insn PARAMS ((struct m68hc11_opcode *,
179 operand *, int, int));
180static int build_indexed_byte PARAMS ((operand *, int, int));
181static int build_reg_mode PARAMS ((operand *, int));
182
183static struct m68hc11_opcode *find
184 PARAMS ((struct m68hc11_opcode_def *, operand *, int));
185static struct m68hc11_opcode *find_opcode
186 PARAMS ((struct m68hc11_opcode_def *, operand *, int *));
187static void build_jump_insn
188 PARAMS ((struct m68hc11_opcode *, operand *, int, int));
189static void build_insn
190 PARAMS ((struct m68hc11_opcode *, operand *, int));
191static int relaxable_symbol PARAMS ((symbolS *));
192
193/* Pseudo op to indicate a relax group. */
194static void s_m68hc11_relax PARAMS((int));
195
196/* Pseudo op to control the ELF flags. */
197static void s_m68hc11_mode PARAMS ((int));
198
199/* Mark the symbols with STO_M68HC12_FAR to indicate the functions
200 are using 'rtc' for returning. It is necessary to use 'call'
201 to invoke them. This is also used by the debugger to correctly
202 find the stack frame. */
203static void s_m68hc11_mark_symbol PARAMS ((int));
204
205/* Controls whether relative branches can be turned into long branches.
206 When the relative offset is too large, the insn are changed:
207 bra -> jmp
208 bsr -> jsr
209 bcc -> b!cc +3
210 jmp L
211 dbcc -> db!cc +3
212 jmp L
213
214 Setting the flag forbidds this. */
215static short flag_fixed_branchs = 0;
216
217/* Force to use long jumps (absolute) instead of relative branches. */
218static short flag_force_long_jumps = 0;
219
220/* Change the direct addressing mode into an absolute addressing mode
221 when the insn does not support direct addressing.
222 For example, "clr *ZD0" is normally not possible and is changed
223 into "clr ZDO". */
224static short flag_strict_direct_addressing = 1;
225
226/* When an opcode has invalid operand, print out the syntax of the opcode
227 to stderr. */
228static short flag_print_insn_syntax = 0;
229
230/* Dumps the list of instructions with syntax and then exit:
231 1 -> Only dumps the list (sorted by name)
232 2 -> Generate an example (or test) that can be compiled. */
233static short flag_print_opcodes = 0;
234
235/* Opcode hash table. */
236static struct hash_control *m68hc11_hash;
237
238/* Current cpu (either cpu6811 or cpu6812). This is determined automagically
239 by 'get_default_target' by looking at default BFD vector. This is overriden
240 with the -m<cpu> option. */
241static int current_architecture = 0;
242
243/* Default cpu determined by 'get_default_target'. */
244static const char *default_cpu;
245
246/* Number of opcodes in the sorted table (filtered by current cpu). */
247static int num_opcodes;
248
249/* The opcodes sorted by name and filtered by current cpu. */
250static struct m68hc11_opcode *m68hc11_sorted_opcodes;
251
252/* ELF flags to set in the output file header. */
253static int elf_flags = E_M68HC11_F64;
254
255/* These are the machine dependent pseudo-ops. These are included so
256 the assembler can work on the output from the SUN C compiler, which
257 generates these. */
258
259/* This table describes all the machine specific pseudo-ops the assembler
260 has to support. The fields are:
261 pseudo-op name without dot
262 function to call to execute this pseudo-op
263 Integer arg to pass to the function. */
264const pseudo_typeS md_pseudo_table[] = {
265 /* The following pseudo-ops are supported for MRI compatibility. */
266 {"fcb", cons, 1},
267 {"fdb", cons, 2},
268 {"fcc", stringer, 1},
269 {"rmb", s_space, 0},
270
271 /* Dwarf2 support for Gcc. */
272 {"file", (void (*) PARAMS ((int))) dwarf2_directive_file, 0},
273 {"loc", dwarf2_directive_loc, 0},
274
275 /* Motorola ALIS. */
276 {"xrefb", s_ignore, 0}, /* Same as xref */
277
278 /* Gcc driven relaxation. */
279 {"relax", s_m68hc11_relax, 0},
280
281 /* .mode instruction (ala SH). */
282 {"mode", s_m68hc11_mode, 0},
283
284 /* .far instruction. */
285 {"far", s_m68hc11_mark_symbol, STO_M68HC12_FAR},
286
287 /* .interrupt instruction. */
288 {"interrupt", s_m68hc11_mark_symbol, STO_M68HC12_INTERRUPT},
289
290 {0, 0, 0}
291};
292
293
294/* Options and initialization. */
295
296const char *md_shortopts = "Sm:";
297
298struct option md_longopts[] = {
299#define OPTION_FORCE_LONG_BRANCH (OPTION_MD_BASE)
300 {"force-long-branchs", no_argument, NULL, OPTION_FORCE_LONG_BRANCH},
301
302#define OPTION_SHORT_BRANCHS (OPTION_MD_BASE + 1)
303 {"short-branchs", no_argument, NULL, OPTION_SHORT_BRANCHS},
304
305#define OPTION_STRICT_DIRECT_MODE (OPTION_MD_BASE + 2)
306 {"strict-direct-mode", no_argument, NULL, OPTION_STRICT_DIRECT_MODE},
307
308#define OPTION_PRINT_INSN_SYNTAX (OPTION_MD_BASE + 3)
309 {"print-insn-syntax", no_argument, NULL, OPTION_PRINT_INSN_SYNTAX},
310
311#define OPTION_PRINT_OPCODES (OPTION_MD_BASE + 4)
312 {"print-opcodes", no_argument, NULL, OPTION_PRINT_OPCODES},
313
314#define OPTION_GENERATE_EXAMPLE (OPTION_MD_BASE + 5)
315 {"generate-example", no_argument, NULL, OPTION_GENERATE_EXAMPLE},
316
317#define OPTION_MSHORT (OPTION_MD_BASE + 6)
318 {"mshort", no_argument, NULL, OPTION_MSHORT},
319
320#define OPTION_MLONG (OPTION_MD_BASE + 7)
321 {"mlong", no_argument, NULL, OPTION_MLONG},
322
323#define OPTION_MSHORT_DOUBLE (OPTION_MD_BASE + 8)
324 {"mshort-double", no_argument, NULL, OPTION_MSHORT_DOUBLE},
325
326#define OPTION_MLONG_DOUBLE (OPTION_MD_BASE + 9)
327 {"mlong-double", no_argument, NULL, OPTION_MLONG_DOUBLE},
328
329 {NULL, no_argument, NULL, 0}
330};
331size_t md_longopts_size = sizeof (md_longopts);
332
333/* Get the target cpu for the assembler. This is based on the configure
334 options and on the -m68hc11/-m68hc12 option. If no option is specified,
335 we must get the default. */
336const char *
337m68hc11_arch_format ()
338{
339 get_default_target ();
340 if (current_architecture & cpu6811)
341 return "elf32-m68hc11";
342 else
343 return "elf32-m68hc12";
344}
345
346enum bfd_architecture
347m68hc11_arch ()
348{
349 get_default_target ();
350 if (current_architecture & cpu6811)
351 return bfd_arch_m68hc11;
352 else
353 return bfd_arch_m68hc12;
354}
355
356int
357m68hc11_mach ()
358{
359 return 0;
360}
361
362/* Listing header selected according to cpu. */
363const char *
364m68hc11_listing_header ()
365{
366 if (current_architecture & cpu6811)
367 return "M68HC11 GAS ";
368 else
369 return "M68HC12 GAS ";
370}
371
372void
373md_show_usage (stream)
374 FILE *stream;
375{
376 get_default_target ();
377 fprintf (stream, _("\
378Motorola 68HC11/68HC12/68HCS12 options:\n\
379 -m68hc11 | -m68hc12 |\n\
380 -m68hcs12 specify the processor [default %s]\n\
381 -mshort use 16-bit int ABI (default)\n\
382 -mlong use 32-bit int ABI\n\
383 -mshort-double use 32-bit double ABI\n\
384 -mlong-double use 64-bit double ABI (default)\n\
385 --force-long-branchs always turn relative branchs into absolute ones\n\
386 -S,--short-branchs do not turn relative branchs into absolute ones\n\
387 when the offset is out of range\n\
388 --strict-direct-mode do not turn the direct mode into extended mode\n\
389 when the instruction does not support direct mode\n\
390 --print-insn-syntax print the syntax of instruction in case of error\n\
391 --print-opcodes print the list of instructions with syntax\n\
392 --generate-example generate an example of each instruction\n\
393 (used for testing)\n"), default_cpu);
394
395}
396
397/* Try to identify the default target based on the BFD library. */
398static void
399get_default_target ()
400{
401 const bfd_target *target;
402 bfd abfd;
403
404 if (current_architecture != 0)
405 return;
406
407 default_cpu = "unknown";
408 target = bfd_find_target (0, &abfd);
409 if (target && target->name)
410 {
411 if (strcmp (target->name, "elf32-m68hc12") == 0)
412 {
413 current_architecture = cpu6812;
414 default_cpu = "m68hc12";
415 }
416 else if (strcmp (target->name, "elf32-m68hc11") == 0)
417 {
418 current_architecture = cpu6811;
419 default_cpu = "m68hc11";
420 }
421 else
422 {
423 as_bad (_("Default target `%s' is not supported."), target->name);
424 }
425 }
426}
427
428void
429m68hc11_print_statistics (file)
430 FILE *file;
431{
432 int i;
433 struct m68hc11_opcode_def *opc;
434
435 hash_print_statistics (file, "opcode table", m68hc11_hash);
436
437 opc = m68hc11_opcode_defs;
438 if (opc == 0 || m68hc11_nb_opcode_defs == 0)
439 return;
440
441 /* Dump the opcode statistics table. */
442 fprintf (file, _("Name # Modes Min ops Max ops Modes mask # Used\n"));
443 for (i = 0; i < m68hc11_nb_opcode_defs; i++, opc++)
444 {
445 fprintf (file, "%-7.7s %5d %7d %7d 0x%08lx %7d\n",
446 opc->opcode->name,
447 opc->nb_modes,
448 opc->min_operands, opc->max_operands, opc->format, opc->used);
449 }
450}
451
452int
453md_parse_option (c, arg)
454 int c;
455 char *arg;
456{
457 get_default_target ();
458 switch (c)
459 {
460 /* -S means keep external to 2 bit offset rather than 16 bit one. */
461 case OPTION_SHORT_BRANCHS:
462 case 'S':
463 flag_fixed_branchs = 1;
464 break;
465
466 case OPTION_FORCE_LONG_BRANCH:
467 flag_force_long_jumps = 1;
468 break;
469
470 case OPTION_PRINT_INSN_SYNTAX:
471 flag_print_insn_syntax = 1;
472 break;
473
474 case OPTION_PRINT_OPCODES:
475 flag_print_opcodes = 1;
476 break;
477
478 case OPTION_STRICT_DIRECT_MODE:
479 flag_strict_direct_addressing = 0;
480 break;
481
482 case OPTION_GENERATE_EXAMPLE:
483 flag_print_opcodes = 2;
484 break;
485
486 case OPTION_MSHORT:
487 elf_flags &= ~E_M68HC11_I32;
488 break;
489
490 case OPTION_MLONG:
491 elf_flags |= E_M68HC11_I32;
492 break;
493
494 case OPTION_MSHORT_DOUBLE:
495 elf_flags &= ~E_M68HC11_F64;
496 break;
497
498 case OPTION_MLONG_DOUBLE:
499 elf_flags |= E_M68HC11_F64;
500 break;
501
502 case 'm':
503 if (strcasecmp (arg, "68hc11") == 0)
504 current_architecture = cpu6811;
505 else if (strcasecmp (arg, "68hc12") == 0)
506 current_architecture = cpu6812;
507 else if (strcasecmp (arg, "68hcs12") == 0)
508 current_architecture = cpu6812 | cpu6812s;
509 else
510 as_bad (_("Option `%s' is not recognized."), arg);
511 break;
512
513 default:
514 return 0;
515 }
516
517 return 1;
518}
519
520
521symbolS *
522md_undefined_symbol (name)
523 char *name ATTRIBUTE_UNUSED;
524{
525 return 0;
526}
527
528/* Equal to MAX_PRECISION in atof-ieee.c. */
529#define MAX_LITTLENUMS 6
530
531/* Turn a string in input_line_pointer into a floating point constant
532 of type TYPE, and store the appropriate bytes in *LITP. The number
533 of LITTLENUMS emitted is stored in *SIZEP. An error message is
534 returned, or NULL on OK. */
535char *
536md_atof (type, litP, sizeP)
537 char type;
538 char *litP;
539 int *sizeP;
540{
541 int prec;
542 LITTLENUM_TYPE words[MAX_LITTLENUMS];
543 LITTLENUM_TYPE *wordP;
544 char *t;
545
546 switch (type)
547 {
548 case 'f':
549 case 'F':
550 case 's':
551 case 'S':
552 prec = 2;
553 break;
554
555 case 'd':
556 case 'D':
557 case 'r':
558 case 'R':
559 prec = 4;
560 break;
561
562 case 'x':
563 case 'X':
564 prec = 6;
565 break;
566
567 case 'p':
568 case 'P':
569 prec = 6;
570 break;
571
572 default:
573 *sizeP = 0;
574 return _("Bad call to MD_ATOF()");
575 }
576 t = atof_ieee (input_line_pointer, type, words);
577 if (t)
578 input_line_pointer = t;
579
580 *sizeP = prec * sizeof (LITTLENUM_TYPE);
581 for (wordP = words; prec--;)
582 {
583 md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE));
584 litP += sizeof (LITTLENUM_TYPE);
585 }
586 return 0;
587}
588
589valueT
590md_section_align (seg, addr)
591 asection *seg;
592 valueT addr;
593{
594 int align = bfd_get_section_alignment (stdoutput, seg);
595 return ((addr + (1 << align) - 1) & (-1 << align));
596}
597
598static int
599cmp_opcode (op1, op2)
600 struct m68hc11_opcode *op1;
601 struct m68hc11_opcode *op2;
602{
603 return strcmp (op1->name, op2->name);
604}
605
606#define IS_CALL_SYMBOL(MODE) \
607(((MODE) & (M6812_OP_PAGE|M6811_OP_IND16)) \
608 == ((M6812_OP_PAGE|M6811_OP_IND16)))
609
610/* Initialize the assembler. Create the opcode hash table
611 (sorted on the names) with the M6811 opcode table
612 (from opcode library). */
613void
614md_begin ()
615{
616 char *prev_name = "";
617 struct m68hc11_opcode *opcodes;
618 struct m68hc11_opcode_def *opc = 0;
619 int i, j;
620
621 get_default_target ();
622
623 m68hc11_hash = hash_new ();
624
625 /* Get a writable copy of the opcode table and sort it on the names. */
626 opcodes = (struct m68hc11_opcode *) xmalloc (m68hc11_num_opcodes *
627 sizeof (struct
628 m68hc11_opcode));
629 m68hc11_sorted_opcodes = opcodes;
630 num_opcodes = 0;
631 for (i = 0; i < m68hc11_num_opcodes; i++)
632 {
633 if (m68hc11_opcodes[i].arch & current_architecture)
634 {
635 opcodes[num_opcodes] = m68hc11_opcodes[i];
636 if (opcodes[num_opcodes].name[0] == 'b'
637 && opcodes[num_opcodes].format & M6811_OP_JUMP_REL
638 && !(opcodes[num_opcodes].format & M6811_OP_BITMASK))
639 {
640 num_opcodes++;
641 opcodes[num_opcodes] = m68hc11_opcodes[i];
642 }
643 num_opcodes++;
644 for (j = 0; alias_opcodes[j].name != 0; j++)
645 if (strcmp (m68hc11_opcodes[i].name, alias_opcodes[j].name) == 0)
646 {
647 opcodes[num_opcodes] = m68hc11_opcodes[i];
648 opcodes[num_opcodes].name = alias_opcodes[j].alias;
649 num_opcodes++;
650 break;
651 }
652 }
653 }
654 qsort (opcodes, num_opcodes, sizeof (struct m68hc11_opcode),
655 (int (*) PARAMS ((const PTR, const PTR))) cmp_opcode);
656
657 opc = (struct m68hc11_opcode_def *)
658 xmalloc (num_opcodes * sizeof (struct m68hc11_opcode_def));
659 m68hc11_opcode_defs = opc--;
660
661 /* Insert unique names into hash table. The M6811 instruction set
662 has several identical opcode names that have different opcodes based
663 on the operands. This hash table then provides a quick index to
664 the first opcode with a particular name in the opcode table. */
665 for (i = 0; i < num_opcodes; i++, opcodes++)
666 {
667 int expect;
668
669 if (strcmp (prev_name, opcodes->name))
670 {
671 prev_name = (char *) opcodes->name;
672
673 opc++;
674 opc->format = 0;
675 opc->min_operands = 100;
676 opc->max_operands = 0;
677 opc->nb_modes = 0;
678 opc->opcode = opcodes;
679 opc->used = 0;
680 hash_insert (m68hc11_hash, opcodes->name, (char *) opc);
681 }
682 opc->nb_modes++;
683 opc->format |= opcodes->format;
684
685 /* See how many operands this opcode needs. */
686 expect = 0;
687 if (opcodes->format & M6811_OP_MASK)
688 expect++;
689 if (opcodes->format & M6811_OP_BITMASK)
690 expect++;
691 if (opcodes->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
692 expect++;
693 if (opcodes->format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2))
694 expect++;
695 /* Special case for call instruction. */
696 if ((opcodes->format & M6812_OP_PAGE)
697 && !(opcodes->format & M6811_OP_IND16))
698 expect++;
699
700 if (expect < opc->min_operands)
701 opc->min_operands = expect;
702 if (IS_CALL_SYMBOL (opcodes->format))
703 expect++;
704 if (expect > opc->max_operands)
705 opc->max_operands = expect;
706 }
707 opc++;
708 m68hc11_nb_opcode_defs = opc - m68hc11_opcode_defs;
709
710 if (flag_print_opcodes)
711 {
712 print_opcode_list ();
713 exit (EXIT_SUCCESS);
714 }
715}
716
717void
718m68hc11_init_after_args ()
719{
720}
721
722
723/* Builtin help. */
724
725/* Return a string that represents the operand format for the instruction.
726 When example is true, this generates an example of operand. This is used
727 to give an example and also to generate a test. */
728static char *
729print_opcode_format (opcode, example)
730 struct m68hc11_opcode *opcode;
731 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 if (format & M6811_OP_IMM8)
740 {
741 if (example)
742 sprintf (p, "#%d", rand () & 0x0FF);
743 else
744 strcpy (p, _("#<imm8>"));
745 p = &p[strlen (p)];
746 }
747
748 if (format & M6811_OP_IMM16)
749 {
750 if (example)
751 sprintf (p, "#%d", rand () & 0x0FFFF);
752 else
753 strcpy (p, _("#<imm16>"));
754 p = &p[strlen (p)];
755 }
756
757 if (format & M6811_OP_IX)
758 {
759 if (example)
760 sprintf (p, "%d,X", rand () & 0x0FF);
761 else
762 strcpy (p, _("<imm8>,X"));
763 p = &p[strlen (p)];
764 }
765
766 if (format & M6811_OP_IY)
767 {
768 if (example)
769 sprintf (p, "%d,X", rand () & 0x0FF);
770 else
771 strcpy (p, _("<imm8>,X"));
772 p = &p[strlen (p)];
773 }
774
775 if (format & M6812_OP_IDX)
776 {
777 if (example)
778 sprintf (p, "%d,X", rand () & 0x0FF);
779 else
780 strcpy (p, "n,r");
781 p = &p[strlen (p)];
782 }
783
784 if (format & M6812_OP_PAGE)
785 {
786 if (example)
787 sprintf (p, ", %d", rand () & 0x0FF);
788 else
789 strcpy (p, ", <page>");
790 p = &p[strlen (p)];
791 }
792
793 if (format & M6811_OP_DIRECT)
794 {
795 if (example)
796 sprintf (p, "*Z%d", rand () & 0x0FF);
797 else
798 strcpy (p, _("*<abs8>"));
799 p = &p[strlen (p)];
800 }
801
802 if (format & M6811_OP_BITMASK)
803 {
804 if (buf[0])
805 *p++ = ' ';
806
807 if (example)
808 sprintf (p, "#$%02x", rand () & 0x0FF);
809 else
810 strcpy (p, _("#<mask>"));
811
812 p = &p[strlen (p)];
813 if (format & M6811_OP_JUMP_REL)
814 *p++ = ' ';
815 }
816
817 if (format & M6811_OP_IND16)
818 {
819 if (example)
820 sprintf (p, _("symbol%d"), rand () & 0x0FF);
821 else
822 strcpy (p, _("<abs>"));
823
824 p = &p[strlen (p)];
825 }
826
827 if (format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
828 {
829 if (example)
830 {
831 if (format & M6811_OP_BITMASK)
832 {
833 sprintf (p, ".+%d", rand () & 0x7F);
834 }
835 else
836 {
837 sprintf (p, "L%d", rand () & 0x0FF);
838 }
839 }
840 else
841 strcpy (p, _("<label>"));
842 }
843
844 return buf;
845}
846
847/* Prints the list of instructions with the possible operands. */
848static void
849print_opcode_list ()
850{
851 int i;
852 char *prev_name = "";
853 struct m68hc11_opcode *opcodes;
854 int example = flag_print_opcodes == 2;
855
856 if (example)
857 printf (_("# Example of `%s' instructions\n\t.sect .text\n_start:\n"),
858 default_cpu);
859
860 opcodes = m68hc11_sorted_opcodes;
861
862 /* Walk the list sorted on names (by md_begin). We only report
863 one instruction per line, and we collect the different operand
864 formats. */
865 for (i = 0; i < num_opcodes; i++, opcodes++)
866 {
867 char *fmt = print_opcode_format (opcodes, example);
868
869 if (example)
870 {
871 printf ("L%d:\t", i);
872 printf ("%s %s\n", opcodes->name, fmt);
873 }
874 else
875 {
876 if (strcmp (prev_name, opcodes->name))
877 {
878 if (i > 0)
879 printf ("\n");
880
881 printf ("%-5.5s ", opcodes->name);
882 prev_name = (char *) opcodes->name;
883 }
884 if (fmt[0])
885 printf (" [%s]", fmt);
886 }
887 }
888 printf ("\n");
889}
890
891/* Print the instruction format. This operation is called when some
892 instruction is not correct. Instruction format is printed as an
893 error message. */
894static void
895print_insn_format (name)
896 char *name;
897{
898 struct m68hc11_opcode_def *opc;
899 struct m68hc11_opcode *opcode;
900 char buf[128];
901
902 opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash, name);
903 if (opc == NULL)
904 {
905 as_bad (_("Instruction `%s' is not recognized."), name);
906 return;
907 }
908 opcode = opc->opcode;
909
910 as_bad (_("Instruction formats for `%s':"), name);
911 do
912 {
913 char *fmt;
914
915 fmt = print_opcode_format (opcode, 0);
916 sprintf (buf, "\t%-5.5s %s", opcode->name, fmt);
917
918 as_bad ("%s", buf);
919 opcode++;
920 }
921 while (strcmp (opcode->name, name) == 0);
922}
923
924
925/* Analysis of 68HC11 and 68HC12 operands. */
926
927/* reg_name_search() finds the register number given its name.
928 Returns the register number or REG_NONE on failure. */
929static register_id
930reg_name_search (name)
931 char *name;
932{
933 if (strcasecmp (name, "x") == 0 || strcasecmp (name, "ix") == 0)
934 return REG_X;
935 if (strcasecmp (name, "y") == 0 || strcasecmp (name, "iy") == 0)
936 return REG_Y;
937 if (strcasecmp (name, "a") == 0)
938 return REG_A;
939 if (strcasecmp (name, "b") == 0)
940 return REG_B;
941 if (strcasecmp (name, "d") == 0)
942 return REG_D;
943 if (strcasecmp (name, "sp") == 0)
944 return REG_SP;
945 if (strcasecmp (name, "pc") == 0)
946 return REG_PC;
947 if (strcasecmp (name, "ccr") == 0)
948 return REG_CCR;
949
950 return REG_NONE;
951}
952
953static char *
954skip_whites (p)
955 char *p;
956{
957 while (*p == ' ' || *p == '\t')
958 p++;
959
960 return p;
961}
962
963/* Check the string at input_line_pointer
964 to see if it is a valid register name. */
965static register_id
966register_name ()
967{
968 register_id reg_number;
969 char c, *p = input_line_pointer;
970
971 if (!is_name_beginner (*p++))
972 return REG_NONE;
973
974 while (is_part_of_name (*p++))
975 continue;
976
977 c = *--p;
978 if (c)
979 *p++ = 0;
980
981 /* Look to see if it's in the register table. */
982 reg_number = reg_name_search (input_line_pointer);
983 if (reg_number != REG_NONE)
984 {
985 if (c)
986 *--p = c;
987
988 input_line_pointer = p;
989 return reg_number;
990 }
991 if (c)
992 *--p = c;
993
994 return reg_number;
995}
996#define M6811_OP_CALL_ADDR 0x00800000
997#define M6811_OP_PAGE_ADDR 0x04000000
998
999/* Parse a string of operands and return an array of expressions.
1000
1001 Operand mode[0] mode[1] exp[0] exp[1]
1002 #n M6811_OP_IMM16 - O_*
1003 *<exp> M6811_OP_DIRECT - O_*
1004 .{+-}<exp> M6811_OP_JUMP_REL - O_*
1005 <exp> M6811_OP_IND16 - O_*
1006 ,r N,r M6812_OP_IDX M6812_OP_REG O_constant O_register
1007 n,-r M6812_PRE_DEC M6812_OP_REG O_constant O_register
1008 n,+r M6812_PRE_INC " "
1009 n,r- M6812_POST_DEC " "
1010 n,r+ M6812_POST_INC " "
1011 A,r B,r D,r M6811_OP_REG M6812_OP_REG O_register O_register
1012 [D,r] M6811_OP_D_IDX M6812_OP_REG O_register O_register
1013 [n,r] M6811_OP_D_IDX_2 M6812_OP_REG O_constant O_register */
1014static int
1015get_operand (oper, which, opmode)
1016 operand *oper;
1017 int which;
1018 long opmode;
1019{
1020 char *p = input_line_pointer;
1021 int mode;
1022 register_id reg;
1023
1024 oper->exp.X_op = O_absent;
1025 oper->reg1 = REG_NONE;
1026 oper->reg2 = REG_NONE;
1027 mode = M6811_OP_NONE;
1028
1029 p = skip_whites (p);
1030
1031 if (*p == 0 || *p == '\n' || *p == '\r')
1032 {
1033 input_line_pointer = p;
1034 return 0;
1035 }
1036
1037 if (*p == '*' && (opmode & (M6811_OP_DIRECT | M6811_OP_IND16)))
1038 {
1039 mode = M6811_OP_DIRECT;
1040 p++;
1041 }
1042 else if (*p == '#')
1043 {
1044 if (!(opmode & (M6811_OP_IMM8 | M6811_OP_IMM16 | M6811_OP_BITMASK)))
1045 {
1046 as_bad (_("Immediate operand is not allowed for operand %d."),
1047 which);
1048 return -1;
1049 }
1050
1051 mode = M6811_OP_IMM16;
1052 p++;
1053 if (strncmp (p, "%hi", 3) == 0)
1054 {
1055 p += 3;
1056 mode |= M6811_OP_HIGH_ADDR;
1057 }
1058 else if (strncmp (p, "%lo", 3) == 0)
1059 {
1060 p += 3;
1061 mode |= M6811_OP_LOW_ADDR;
1062 }
1063 /* %page modifier is used to obtain only the page number
1064 of the address of a function. */
1065 else if (strncmp (p, "%page", 5) == 0)
1066 {
1067 p += 5;
1068 mode |= M6811_OP_PAGE_ADDR;
1069 }
1070
1071 /* %addr modifier is used to obtain the physical address part
1072 of the function (16-bit). For 68HC12 the function will be
1073 mapped in the 16K window at 0x8000 and the value will be
1074 within that window (although the function address may not fit
1075 in 16-bit). See bfd/elf32-m68hc12.c for the translation. */
1076 else if (strncmp (p, "%addr", 5) == 0)
1077 {
1078 p += 5;
1079 mode |= M6811_OP_CALL_ADDR;
1080 }
1081 }
1082 else if (*p == '.' && (p[1] == '+' || p[1] == '-'))
1083 {
1084 p++;
1085 mode = M6811_OP_JUMP_REL;
1086 }
1087 else if (*p == '[')
1088 {
1089 if (current_architecture & cpu6811)
1090 as_bad (_("Indirect indexed addressing is not valid for 68HC11."));
1091
1092 p++;
1093 mode = M6812_OP_D_IDX;
1094 p = skip_whites (p);
1095 }
1096 else if (*p == ',') /* Special handling of ,x and ,y. */
1097 {
1098 p++;
1099 input_line_pointer = p;
1100
1101 reg = register_name ();
1102 if (reg != REG_NONE)
1103 {
1104 oper->reg1 = reg;
1105 oper->exp.X_op = O_constant;
1106 oper->exp.X_add_number = 0;
1107 oper->mode = M6812_OP_IDX;
1108 return 1;
1109 }
1110 as_bad (_("Spurious `,' or bad indirect register addressing mode."));
1111 return -1;
1112 }
1113 /* Handle 68HC12 page specification in 'call foo,%page(bar)'. */
1114 else if ((opmode & M6812_OP_PAGE) && strncmp (p, "%page", 5) == 0)
1115 {
1116 p += 5;
1117 mode = M6811_OP_PAGE_ADDR | M6812_OP_PAGE | M6811_OP_IND16;
1118 }
1119 input_line_pointer = p;
1120
1121 if (mode == M6811_OP_NONE || mode == M6812_OP_D_IDX)
1122 reg = register_name ();
1123 else
1124 reg = REG_NONE;
1125
1126 if (reg != REG_NONE)
1127 {
1128 p = skip_whites (input_line_pointer);
1129 if (*p == ']' && mode == M6812_OP_D_IDX)
1130 {
1131 as_bad
1132 (_("Missing second register or offset for indexed-indirect mode."));
1133 return -1;
1134 }
1135
1136 oper->reg1 = reg;
1137 oper->mode = mode | M6812_OP_REG;
1138 if (*p != ',')
1139 {
1140 if (mode == M6812_OP_D_IDX)
1141 {
1142 as_bad (_("Missing second register for indexed-indirect mode."));
1143 return -1;
1144 }
1145 return 1;
1146 }
1147
1148 p++;
1149 input_line_pointer = p;
1150 reg = register_name ();
1151 if (reg != REG_NONE)
1152 {
1153 p = skip_whites (input_line_pointer);
1154 if (mode == M6812_OP_D_IDX)
1155 {
1156 if (*p != ']')
1157 {
1158 as_bad (_("Missing `]' to close indexed-indirect mode."));
1159 return -1;
1160 }
1161 p++;
1162 oper->mode = M6812_OP_D_IDX;
1163 }
1164 input_line_pointer = p;
1165
1166 oper->reg2 = reg;
1167 return 1;
1168 }
1169 return 1;
1170 }
1171
1172 /* In MRI mode, isolate the operand because we can't distinguish
1173 operands from comments. */
1174 if (flag_mri)
1175 {
1176 char c = 0;
1177
1178 p = skip_whites (p);
1179 while (*p && *p != ' ' && *p != '\t')
1180 p++;
1181
1182 if (*p)
1183 {
1184 c = *p;
1185 *p = 0;
1186 }
1187
1188 /* Parse as an expression. */
1189 expression (&oper->exp);
1190
1191 if (c)
1192 {
1193 *p = c;
1194 }
1195 }
1196 else
1197 {
1198 expression (&oper->exp);
1199 }
1200
1201 if (oper->exp.X_op == O_illegal)
1202 {
1203 as_bad (_("Illegal operand."));
1204 return -1;
1205 }
1206 else if (oper->exp.X_op == O_absent)
1207 {
1208 as_bad (_("Missing operand."));
1209 return -1;
1210 }
1211
1212 p = input_line_pointer;
1213
1214 if (mode == M6811_OP_NONE || mode == M6811_OP_DIRECT
1215 || mode == M6812_OP_D_IDX)
1216 {
1217 p = skip_whites (input_line_pointer);
1218
1219 if (*p == ',')
1220 {
1221 int possible_mode = M6811_OP_NONE;
1222 char *old_input_line;
1223
1224 old_input_line = p;
1225 p++;
1226
1227 /* 68HC12 pre increment or decrement. */
1228 if (mode == M6811_OP_NONE)
1229 {
1230 if (*p == '-')
1231 {
1232 possible_mode = M6812_PRE_DEC;
1233 p++;
1234 }
1235 else if (*p == '+')
1236 {
1237 possible_mode = M6812_PRE_INC;
1238 p++;
1239 }
1240 p = skip_whites (p);
1241 }
1242 input_line_pointer = p;
1243 reg = register_name ();
1244
1245 /* Backtrack if we have a valid constant expression and
1246 it does not correspond to the offset of the 68HC12 indexed
1247 addressing mode (as in N,x). */
1248 if (reg == REG_NONE && mode == M6811_OP_NONE
1249 && possible_mode != M6811_OP_NONE)
1250 {
1251 oper->mode = M6811_OP_IND16 | M6811_OP_JUMP_REL;
1252 input_line_pointer = skip_whites (old_input_line);
1253 return 1;
1254 }
1255
1256 if (possible_mode != M6811_OP_NONE)
1257 mode = possible_mode;
1258
1259 if ((current_architecture & cpu6811)
1260 && possible_mode != M6811_OP_NONE)
1261 as_bad (_("Pre-increment mode is not valid for 68HC11"));
1262 /* Backtrack. */
1263 if (which == 0 && opmode & M6812_OP_IDX_P2
1264 && reg != REG_X && reg != REG_Y
1265 && reg != REG_PC && reg != REG_SP)
1266 {
1267 reg = REG_NONE;
1268 input_line_pointer = p;
1269 }
1270
1271 if (reg == REG_NONE && mode != M6811_OP_DIRECT
1272 && !(mode == M6811_OP_NONE && opmode & M6811_OP_IND16))
1273 {
1274 as_bad (_("Wrong register in register indirect mode."));
1275 return -1;
1276 }
1277 if (mode == M6812_OP_D_IDX)
1278 {
1279 p = skip_whites (input_line_pointer);
1280 if (*p++ != ']')
1281 {
1282 as_bad (_("Missing `]' to close register indirect operand."));
1283 return -1;
1284 }
1285 input_line_pointer = p;
1286 oper->reg1 = reg;
1287 oper->mode = M6812_OP_D_IDX_2;
1288 return 1;
1289 }
1290 if (reg != REG_NONE)
1291 {
1292 oper->reg1 = reg;
1293 if (mode == M6811_OP_NONE)
1294 {
1295 p = input_line_pointer;
1296 if (*p == '-')
1297 {
1298 mode = M6812_POST_DEC;
1299 p++;
1300 if (current_architecture & cpu6811)
1301 as_bad
1302 (_("Post-decrement mode is not valid for 68HC11."));
1303 }
1304 else if (*p == '+')
1305 {
1306 mode = M6812_POST_INC;
1307 p++;
1308 if (current_architecture & cpu6811)
1309 as_bad
1310 (_("Post-increment mode is not valid for 68HC11."));
1311 }
1312 else
1313 mode = M6812_OP_IDX;
1314
1315 input_line_pointer = p;
1316 }
1317 else
1318 mode |= M6812_OP_IDX;
1319
1320 oper->mode = mode;
1321 return 1;
1322 }
1323 input_line_pointer = old_input_line;
1324 }
1325
1326 if (mode == M6812_OP_D_IDX_2)
1327 {
1328 as_bad (_("Invalid indexed indirect mode."));
1329 return -1;
1330 }
1331 }
1332
1333 /* If the mode is not known until now, this is either a label
1334 or an indirect address. */
1335 if (mode == M6811_OP_NONE)
1336 mode = M6811_OP_IND16 | M6811_OP_JUMP_REL;
1337
1338 p = input_line_pointer;
1339 while (*p == ' ' || *p == '\t')
1340 p++;
1341 input_line_pointer = p;
1342 oper->mode = mode;
1343
1344 return 1;
1345}
1346
1347#define M6812_AUTO_INC_DEC (M6812_PRE_INC | M6812_PRE_DEC \
1348 | M6812_POST_INC | M6812_POST_DEC)
1349
1350/* Checks that the number 'num' fits for a given mode. */
1351static int
1352check_range (num, mode)
1353 long num;
1354 int mode;
1355{
1356 /* Auto increment and decrement are ok for [-8..8] without 0. */
1357 if (mode & M6812_AUTO_INC_DEC)
1358 return (num != 0 && num <= 8 && num >= -8);
1359
1360 /* The 68HC12 supports 5, 9 and 16-bit offsets. */
1361 if (mode & (M6812_INDEXED_IND | M6812_INDEXED | M6812_OP_IDX))
1362 mode = M6811_OP_IND16;
1363
1364 if (mode & M6812_OP_JUMP_REL16)
1365 mode = M6811_OP_IND16;
1366
1367 mode &= ~M6811_OP_BRANCH;
1368 switch (mode)
1369 {
1370 case M6811_OP_IX:
1371 case M6811_OP_IY:
1372 case M6811_OP_DIRECT:
1373 return (num >= 0 && num <= 255) ? 1 : 0;
1374
1375 case M6811_OP_BITMASK:
1376 case M6811_OP_IMM8:
1377 case M6812_OP_PAGE:
1378 return (((num & 0xFFFFFF00) == 0) || ((num & 0xFFFFFF00) == 0xFFFFFF00))
1379 ? 1 : 0;
1380
1381 case M6811_OP_JUMP_REL:
1382 return (num >= -128 && num <= 127) ? 1 : 0;
1383
1384 case M6811_OP_IND16:
1385 case M6811_OP_IND16 | M6812_OP_PAGE:
1386 case M6811_OP_IMM16:
1387 return (((num & 0xFFFF0000) == 0) || ((num & 0xFFFF0000) == 0xFFFF0000))
1388 ? 1 : 0;
1389
1390 case M6812_OP_IBCC_MARKER:
1391 case M6812_OP_TBCC_MARKER:
1392 case M6812_OP_DBCC_MARKER:
1393 return (num >= -256 && num <= 255) ? 1 : 0;
1394
1395 case M6812_OP_TRAP_ID:
1396 return ((num >= 0x30 && num <= 0x39)
1397 || (num >= 0x40 && num <= 0x0ff)) ? 1 : 0;
1398
1399 default:
1400 return 0;
1401 }
1402}
1403
1404
1405/* Gas fixup generation. */
1406
1407/* Put a 1 byte expression described by 'oper'. If this expression contains
1408 unresolved symbols, generate an 8-bit fixup. */
1409static void
1410fixup8 (oper, mode, opmode)
1411 expressionS *oper;
1412 int mode;
1413 int opmode;
1414{
1415 char *f;
1416
1417 f = frag_more (1);
1418
1419 if (oper->X_op == O_constant)
1420 {
1421 if (mode & M6812_OP_TRAP_ID
1422 && !check_range (oper->X_add_number, M6812_OP_TRAP_ID))
1423 {
1424 static char trap_id_warn_once = 0;
1425
1426 as_bad (_("Trap id `%ld' is out of range."), oper->X_add_number);
1427 if (trap_id_warn_once == 0)
1428 {
1429 trap_id_warn_once = 1;
1430 as_bad (_("Trap id must be within [0x30..0x39] or [0x40..0xff]."));
1431 }
1432 }
1433
1434 if (!(mode & M6812_OP_TRAP_ID)
1435 && !check_range (oper->X_add_number, mode))
1436 {
1437 as_bad (_("Operand out of 8-bit range: `%ld'."), oper->X_add_number);
1438 }
1439 number_to_chars_bigendian (f, oper->X_add_number & 0x0FF, 1);
1440 }
1441 else if (oper->X_op != O_register)
1442 {
1443 if (mode & M6812_OP_TRAP_ID)
1444 as_bad (_("The trap id must be a constant."));
1445
1446 if (mode == M6811_OP_JUMP_REL)
1447 {
1448 fixS *fixp;
1449
1450 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
1451 oper, TRUE, BFD_RELOC_8_PCREL);
1452 fixp->fx_pcrel_adjust = 1;
1453 }
1454 else
1455 {
1456 fixS *fixp;
1457 int reloc;
1458
1459 /* Now create an 8-bit fixup. If there was some %hi, %lo
1460 or %page modifier, generate the reloc accordingly. */
1461 if (opmode & M6811_OP_HIGH_ADDR)
1462 reloc = BFD_RELOC_M68HC11_HI8;
1463 else if (opmode & M6811_OP_LOW_ADDR)
1464 reloc = BFD_RELOC_M68HC11_LO8;
1465 else if (opmode & M6811_OP_PAGE_ADDR)
1466 reloc = BFD_RELOC_M68HC11_PAGE;
1467 else
1468 reloc = BFD_RELOC_8;
1469
1470 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
1471 oper, FALSE, reloc);
1472 if (reloc != BFD_RELOC_8)
1473 fixp->fx_no_overflow = 1;
1474 }
1475 number_to_chars_bigendian (f, 0, 1);
1476 }
1477 else
1478 {
1479 as_fatal (_("Operand `%x' not recognized in fixup8."), oper->X_op);
1480 }
1481}
1482
1483/* Put a 2 byte expression described by 'oper'. If this expression contains
1484 unresolved symbols, generate a 16-bit fixup. */
1485static void
1486fixup16 (oper, mode, opmode)
1487 expressionS *oper;
1488 int mode;
1489 int opmode ATTRIBUTE_UNUSED;
1490{
1491 char *f;
1492
1493 f = frag_more (2);
1494
1495 if (oper->X_op == O_constant)
1496 {
1497 if (!check_range (oper->X_add_number, mode))
1498 {
1499 as_bad (_("Operand out of 16-bit range: `%ld'."),
1500 oper->X_add_number);
1501 }
1502 number_to_chars_bigendian (f, oper->X_add_number & 0x0FFFF, 2);
1503 }
1504 else if (oper->X_op != O_register)
1505 {
1506 fixS *fixp;
1507 int reloc;
1508
1509 if ((opmode & M6811_OP_CALL_ADDR) && (mode & M6811_OP_IMM16))
1510 reloc = BFD_RELOC_M68HC11_LO16;
1511 else if (mode & M6812_OP_JUMP_REL16)
1512 reloc = BFD_RELOC_16_PCREL;
1513 else if (mode & M6812_OP_PAGE)
1514 reloc = BFD_RELOC_M68HC11_LO16;
1515 else
1516 reloc = BFD_RELOC_16;
1517
1518 /* Now create a 16-bit fixup. */
1519 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 2,
1520 oper,
1521 reloc == BFD_RELOC_16_PCREL,
1522 reloc);
1523 number_to_chars_bigendian (f, 0, 2);
1524 if (reloc == BFD_RELOC_16_PCREL)
1525 fixp->fx_pcrel_adjust = 2;
1526 if (reloc == BFD_RELOC_M68HC11_LO16)
1527 fixp->fx_no_overflow = 1;
1528 }
1529 else
1530 {
1531 as_fatal (_("Operand `%x' not recognized in fixup16."), oper->X_op);
1532 }
1533}
1534
1535/* Put a 3 byte expression described by 'oper'. If this expression contains
1536 unresolved symbols, generate a 24-bit fixup. */
1537static void
1538fixup24 (oper, mode, opmode)
1539 expressionS *oper;
1540 int mode;
1541 int opmode ATTRIBUTE_UNUSED;
1542{
1543 char *f;
1544
1545 f = frag_more (3);
1546
1547 if (oper->X_op == O_constant)
1548 {
1549 if (!check_range (oper->X_add_number, mode))
1550 {
1551 as_bad (_("Operand out of 16-bit range: `%ld'."),
1552 oper->X_add_number);
1553 }
1554 number_to_chars_bigendian (f, oper->X_add_number & 0x0FFFFFF, 3);
1555 }
1556 else if (oper->X_op != O_register)
1557 {
1558 fixS *fixp;
1559
1560 /* Now create a 24-bit fixup. */
1561 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 2,
1562 oper, FALSE, BFD_RELOC_M68HC11_24);
1563 number_to_chars_bigendian (f, 0, 3);
1564 }
1565 else
1566 {
1567 as_fatal (_("Operand `%x' not recognized in fixup16."), oper->X_op);
1568 }
1569}
1570
1571
1572/* 68HC11 and 68HC12 code generation. */
1573
1574/* Translate the short branch/bsr instruction into a long branch. */
1575static unsigned char
1576convert_branch (code)
1577 unsigned char code;
1578{
1579 if (IS_OPCODE (code, M6812_BSR))
1580 return M6812_JSR;
1581 else if (IS_OPCODE (code, M6811_BSR))
1582 return M6811_JSR;
1583 else if (IS_OPCODE (code, M6811_BRA))
1584 return (current_architecture & cpu6812) ? M6812_JMP : M6811_JMP;
1585 else
1586 as_fatal (_("Unexpected branch conversion with `%x'"), code);
1587
1588 /* Keep gcc happy. */
1589 return M6811_JSR;
1590}
1591
1592/* Start a new insn that contains at least 'size' bytes. Record the
1593 line information of that insn in the dwarf2 debug sections. */
1594static char *
1595m68hc11_new_insn (size)
1596 int size;
1597{
1598 char *f;
1599
1600 f = frag_more (size);
1601
1602 dwarf2_emit_insn (size);
1603
1604 return f;
1605}
1606
1607/* Builds a jump instruction (bra, bcc, bsr). */
1608static void
1609build_jump_insn (opcode, operands, nb_operands, jmp_mode)
1610 struct m68hc11_opcode *opcode;
1611 operand operands[];
1612 int nb_operands;
1613 int jmp_mode;
1614{
1615 unsigned char code;
1616 char *f;
1617 unsigned long n;
1618 fragS *frag;
1619 int where;
1620
1621 /* The relative branch convertion is not supported for
1622 brclr and brset. */
1623 assert ((opcode->format & M6811_OP_BITMASK) == 0);
1624 assert (nb_operands == 1);
1625 assert (operands[0].reg1 == REG_NONE && operands[0].reg2 == REG_NONE);
1626
1627 code = opcode->opcode;
1628
1629 n = operands[0].exp.X_add_number;
1630
1631 /* Turn into a long branch:
1632 - when force long branch option (and not for jbcc pseudos),
1633 - when jbcc and the constant is out of -128..127 range,
1634 - when branch optimization is allowed and branch out of range. */
1635 if ((jmp_mode == 0 && flag_force_long_jumps)
1636 || (operands[0].exp.X_op == O_constant
1637 && (!check_range (n, opcode->format) &&
1638 (jmp_mode == 1 || flag_fixed_branchs == 0))))
1639 {
1640 frag = frag_now;
1641 where = frag_now_fix ();
1642
1643 fix_new (frag_now, frag_now_fix (), 1,
1644 &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
1645
1646 if (code == M6811_BSR || code == M6811_BRA || code == M6812_BSR)
1647 {
1648 code = convert_branch (code);
1649
1650 f = m68hc11_new_insn (1);
1651 number_to_chars_bigendian (f, code, 1);
1652 }
1653 else if (current_architecture & cpu6812)
1654 {
1655 /* 68HC12: translate the bcc into a lbcc. */
1656 f = m68hc11_new_insn (2);
1657 number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1);
1658 number_to_chars_bigendian (f + 1, code, 1);
1659 fixup16 (&operands[0].exp, M6812_OP_JUMP_REL16,
1660 M6812_OP_JUMP_REL16);
1661 return;
1662 }
1663 else
1664 {
1665 /* 68HC11: translate the bcc into b!cc +3; jmp <L>. */
1666 f = m68hc11_new_insn (3);
1667 code ^= 1;
1668 number_to_chars_bigendian (f, code, 1);
1669 number_to_chars_bigendian (f + 1, 3, 1);
1670 number_to_chars_bigendian (f + 2, M6811_JMP, 1);
1671 }
1672 fixup16 (&operands[0].exp, M6811_OP_IND16, M6811_OP_IND16);
1673 return;
1674 }
1675
1676 /* Branch with a constant that must fit in 8-bits. */
1677 if (operands[0].exp.X_op == O_constant)
1678 {
1679 if (!check_range (n, opcode->format))
1680 {
1681 as_bad (_("Operand out of range for a relative branch: `%ld'"),
1682 n);
1683 }
1684 else if (opcode->format & M6812_OP_JUMP_REL16)
1685 {
1686 f = m68hc11_new_insn (4);
1687 number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1);
1688 number_to_chars_bigendian (f + 1, code, 1);
1689 number_to_chars_bigendian (f + 2, n & 0x0ffff, 2);
1690 }
1691 else
1692 {
1693 f = m68hc11_new_insn (2);
1694 number_to_chars_bigendian (f, code, 1);
1695 number_to_chars_bigendian (f + 1, n & 0x0FF, 1);
1696 }
1697 }
1698 else if (opcode->format & M6812_OP_JUMP_REL16)
1699 {
1700 frag = frag_now;
1701 where = frag_now_fix ();
1702
1703 fix_new (frag_now, frag_now_fix (), 1,
1704 &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
1705
1706 f = m68hc11_new_insn (2);
1707 number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1);
1708 number_to_chars_bigendian (f + 1, code, 1);
1709 fixup16 (&operands[0].exp, M6812_OP_JUMP_REL16, M6812_OP_JUMP_REL16);
1710 }
1711 else
1712 {
1713 char *opcode;
1714
1715 frag = frag_now;
1716 where = frag_now_fix ();
1717
1718 fix_new (frag_now, frag_now_fix (), 1,
1719 &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
1720
1721 /* Branch offset must fit in 8-bits, don't do some relax. */
1722 if (jmp_mode == 0 && flag_fixed_branchs)
1723 {
1724 opcode = m68hc11_new_insn (1);
1725 number_to_chars_bigendian (opcode, code, 1);
1726 fixup8 (&operands[0].exp, M6811_OP_JUMP_REL, M6811_OP_JUMP_REL);
1727 }
1728
1729 /* bra/bsr made be changed into jmp/jsr. */
1730 else if (code == M6811_BSR || code == M6811_BRA || code == M6812_BSR)
1731 {
1732 /* Allocate worst case storage. */
1733 opcode = m68hc11_new_insn (3);
1734 number_to_chars_bigendian (opcode, code, 1);
1735 number_to_chars_bigendian (opcode + 1, 0, 1);
1736 frag_variant (rs_machine_dependent, 1, 1,
1737 ENCODE_RELAX (STATE_PC_RELATIVE, STATE_UNDF),
1738 operands[0].exp.X_add_symbol, (offsetT) n,
1739 opcode);
1740 }
1741 else if (current_architecture & cpu6812)
1742 {
1743 opcode = m68hc11_new_insn (2);
1744 number_to_chars_bigendian (opcode, code, 1);
1745 number_to_chars_bigendian (opcode + 1, 0, 1);
1746 frag_var (rs_machine_dependent, 2, 2,
1747 ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_UNDF),
1748 operands[0].exp.X_add_symbol, (offsetT) n, opcode);
1749 }
1750 else
1751 {
1752 opcode = m68hc11_new_insn (2);
1753 number_to_chars_bigendian (opcode, code, 1);
1754 number_to_chars_bigendian (opcode + 1, 0, 1);
1755 frag_var (rs_machine_dependent, 3, 3,
1756 ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_UNDF),
1757 operands[0].exp.X_add_symbol, (offsetT) n, opcode);
1758 }
1759 }
1760}
1761
1762/* Builds a dbne/dbeq/tbne/tbeq instruction. */
1763static void
1764build_dbranch_insn (opcode, operands, nb_operands, jmp_mode)
1765 struct m68hc11_opcode *opcode;
1766 operand operands[];
1767 int nb_operands;
1768 int jmp_mode;
1769{
1770 unsigned char code;
1771 char *f;
1772 unsigned long n;
1773
1774 /* The relative branch convertion is not supported for
1775 brclr and brset. */
1776 assert ((opcode->format & M6811_OP_BITMASK) == 0);
1777 assert (nb_operands == 2);
1778 assert (operands[0].reg1 != REG_NONE);
1779
1780 code = opcode->opcode & 0x0FF;
1781
1782 f = m68hc11_new_insn (1);
1783 number_to_chars_bigendian (f, code, 1);
1784
1785 n = operands[1].exp.X_add_number;
1786 code = operands[0].reg1;
1787
1788 if (operands[0].reg1 == REG_NONE || operands[0].reg1 == REG_CCR
1789 || operands[0].reg1 == REG_PC)
1790 as_bad (_("Invalid register for dbcc/tbcc instruction."));
1791
1792 if (opcode->format & M6812_OP_IBCC_MARKER)
1793 code |= 0x80;
1794 else if (opcode->format & M6812_OP_TBCC_MARKER)
1795 code |= 0x40;
1796
1797 if (!(opcode->format & M6812_OP_EQ_MARKER))
1798 code |= 0x20;
1799
1800 /* Turn into a long branch:
1801 - when force long branch option (and not for jbcc pseudos),
1802 - when jdbcc and the constant is out of -256..255 range,
1803 - when branch optimization is allowed and branch out of range. */
1804 if ((jmp_mode == 0 && flag_force_long_jumps)
1805 || (operands[1].exp.X_op == O_constant
1806 && (!check_range (n, M6812_OP_IBCC_MARKER) &&
1807 (jmp_mode == 1 || flag_fixed_branchs == 0))))
1808 {
1809 f = frag_more (2);
1810 code ^= 0x20;
1811 number_to_chars_bigendian (f, code, 1);
1812 number_to_chars_bigendian (f + 1, M6812_JMP, 1);
1813 fixup16 (&operands[0].exp, M6811_OP_IND16, M6811_OP_IND16);
1814 return;
1815 }
1816
1817 /* Branch with a constant that must fit in 9-bits. */
1818 if (operands[1].exp.X_op == O_constant)
1819 {
1820 if (!check_range (n, M6812_OP_IBCC_MARKER))
1821 {
1822 as_bad (_("Operand out of range for a relative branch: `%ld'"),
1823 n);
1824 }
1825 else
1826 {
1827 if ((long) n < 0)
1828 code |= 0x10;
1829
1830 f = frag_more (2);
1831 number_to_chars_bigendian (f, code, 1);
1832 number_to_chars_bigendian (f + 1, n & 0x0FF, 1);
1833 }
1834 }
1835 else
1836 {
1837 /* Branch offset must fit in 8-bits, don't do some relax. */
1838 if (jmp_mode == 0 && flag_fixed_branchs)
1839 {
1840 fixup8 (&operands[0].exp, M6811_OP_JUMP_REL, M6811_OP_JUMP_REL);
1841 }
1842
1843 else
1844 {
1845 f = frag_more (2);
1846 number_to_chars_bigendian (f, code, 1);
1847 number_to_chars_bigendian (f + 1, 0, 1);
1848 frag_var (rs_machine_dependent, 3, 3,
1849 ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_UNDF),
1850 operands[1].exp.X_add_symbol, (offsetT) n, f);
1851 }
1852 }
1853}
1854
1855#define OP_EXTENDED (M6811_OP_PAGE2 | M6811_OP_PAGE3 | M6811_OP_PAGE4)
1856
1857/* Assemble the post index byte for 68HC12 extended addressing modes. */
1858static int
1859build_indexed_byte (op, format, move_insn)
1860 operand *op;
1861 int format ATTRIBUTE_UNUSED;
1862 int move_insn;
1863{
1864 unsigned char byte = 0;
1865 char *f;
1866 int mode;
1867 long val;
1868
1869 val = op->exp.X_add_number;
1870 mode = op->mode;
1871 if (mode & M6812_AUTO_INC_DEC)
1872 {
1873 byte = 0x20;
1874 if (mode & (M6812_POST_INC | M6812_POST_DEC))
1875 byte |= 0x10;
1876
1877 if (op->exp.X_op == O_constant)
1878 {
1879 if (!check_range (val, mode))
1880 {
1881 as_bad (_("Increment/decrement value is out of range: `%ld'."),
1882 val);
1883 }
1884 if (mode & (M6812_POST_INC | M6812_PRE_INC))
1885 byte |= (val - 1) & 0x07;
1886 else
1887 byte |= (8 - ((val) & 7)) | 0x8;
1888 }
1889 switch (op->reg1)
1890 {
1891 case REG_NONE:
1892 as_fatal (_("Expecting a register."));
1893
1894 case REG_X:
1895 byte |= 0;
1896 break;
1897
1898 case REG_Y:
1899 byte |= 0x40;
1900 break;
1901
1902 case REG_SP:
1903 byte |= 0x80;
1904 break;
1905
1906 default:
1907 as_bad (_("Invalid register for post/pre increment."));
1908 break;
1909 }
1910
1911 f = frag_more (1);
1912 number_to_chars_bigendian (f, byte, 1);
1913 return 1;
1914 }
1915
1916 if (mode & (M6812_OP_IDX | M6812_OP_D_IDX_2))
1917 {
1918 switch (op->reg1)
1919 {
1920 case REG_X:
1921 byte = 0;
1922 break;
1923
1924 case REG_Y:
1925 byte = 1;
1926 break;
1927
1928 case REG_SP:
1929 byte = 2;
1930 break;
1931
1932 case REG_PC:
1933 byte = 3;
1934 break;
1935
1936 default:
1937 as_bad (_("Invalid register."));
1938 break;
1939 }
1940 if (op->exp.X_op == O_constant)
1941 {
1942 if (!check_range (val, M6812_OP_IDX))
1943 {
1944 as_bad (_("Offset out of 16-bit range: %ld."), val);
1945 }
1946
1947 if (move_insn && !(val >= -16 && val <= 15))
1948 {
1949 as_bad (_("Offset out of 5-bit range for movw/movb insn: %ld."),
1950 val);
1951 return -1;
1952 }
1953
1954 if (val >= -16 && val <= 15 && !(mode & M6812_OP_D_IDX_2))
1955 {
1956 byte = byte << 6;
1957 byte |= val & 0x1f;
1958 f = frag_more (1);
1959 number_to_chars_bigendian (f, byte, 1);
1960 return 1;
1961 }
1962 else if (val >= -256 && val <= 255 && !(mode & M6812_OP_D_IDX_2))
1963 {
1964 byte = byte << 3;
1965 byte |= 0xe0;
1966 if (val < 0)
1967 byte |= 0x1;
1968 f = frag_more (2);
1969 number_to_chars_bigendian (f, byte, 1);
1970 number_to_chars_bigendian (f + 1, val & 0x0FF, 1);
1971 return 2;
1972 }
1973 else
1974 {
1975 byte = byte << 3;
1976 if (mode & M6812_OP_D_IDX_2)
1977 byte |= 0xe3;
1978 else
1979 byte |= 0xe2;
1980
1981 f = frag_more (3);
1982 number_to_chars_bigendian (f, byte, 1);
1983 number_to_chars_bigendian (f + 1, val & 0x0FFFF, 2);
1984 return 3;
1985 }
1986 }
1987 if (mode & M6812_OP_D_IDX_2)
1988 {
1989 byte = (byte << 3) | 0xe3;
1990 f = frag_more (1);
1991 number_to_chars_bigendian (f, byte, 1);
1992
1993 fixup16 (&op->exp, 0, 0);
1994 }
1995 else if (op->reg1 != REG_PC)
1996 {
1997 symbolS *sym;
1998 offsetT off;
1999
2000 f = frag_more (1);
2001 number_to_chars_bigendian (f, byte, 1);
2002 sym = op->exp.X_add_symbol;
2003 off = op->exp.X_add_number;
2004 if (op->exp.X_op != O_symbol)
2005 {
2006 sym = make_expr_symbol (&op->exp);
2007 off = 0;
2008 }
2009 frag_var (rs_machine_dependent, 2, 2,
2010 ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_UNDF),
2011 sym, off, f);
2012 }
2013 else
2014 {
2015 f = frag_more (1);
2016 number_to_chars_bigendian (f, byte, 1);
2017 frag_var (rs_machine_dependent, 2, 2,
2018 ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_UNDF),
2019 op->exp.X_add_symbol,
2020 op->exp.X_add_number, f);
2021 }
2022 return 3;
2023 }
2024
2025 if (mode & (M6812_OP_REG | M6812_OP_D_IDX))
2026 {
2027 if (mode & M6812_OP_D_IDX)
2028 {
2029 if (op->reg1 != REG_D)
2030 as_bad (_("Expecting register D for indexed indirect mode."));
2031 if (move_insn)
2032 as_bad (_("Indexed indirect mode is not allowed for movb/movw."));
2033
2034 byte = 0xE7;
2035 }
2036 else
2037 {
2038 switch (op->reg1)
2039 {
2040 case REG_A:
2041 byte = 0xE4;
2042 break;
2043
2044 case REG_B:
2045 byte = 0xE5;
2046 break;
2047
2048 default:
2049 as_bad (_("Invalid accumulator register."));
2050
2051 case REG_D:
2052 byte = 0xE6;
2053 break;
2054 }
2055 }
2056 switch (op->reg2)
2057 {
2058 case REG_X:
2059 break;
2060
2061 case REG_Y:
2062 byte |= (1 << 3);
2063 break;
2064
2065 case REG_SP:
2066 byte |= (2 << 3);
2067 break;
2068
2069 case REG_PC:
2070 byte |= (3 << 3);
2071 break;
2072
2073 default:
2074 as_bad (_("Invalid indexed register."));
2075 break;
2076 }
2077 f = frag_more (1);
2078 number_to_chars_bigendian (f, byte, 1);
2079 return 1;
2080 }
2081
2082 as_fatal (_("Addressing mode not implemented yet."));
2083 return 0;
2084}
2085
2086/* Assemble the 68HC12 register mode byte. */
2087static int
2088build_reg_mode (op, format)
2089 operand *op;
2090 int format;
2091{
2092 unsigned char byte;
2093 char *f;
2094
2095 if (format & M6812_OP_SEX_MARKER
2096 && op->reg1 != REG_A && op->reg1 != REG_B && op->reg1 != REG_CCR)
2097 as_bad (_("Invalid source register for this instruction, use 'tfr'."));
2098 else if (op->reg1 == REG_NONE || op->reg1 == REG_PC)
2099 as_bad (_("Invalid source register."));
2100
2101 if (format & M6812_OP_SEX_MARKER
2102 && op->reg2 != REG_D
2103 && op->reg2 != REG_X && op->reg2 != REG_Y && op->reg2 != REG_SP)
2104 as_bad (_("Invalid destination register for this instruction, use 'tfr'."));
2105 else if (op->reg2 == REG_NONE || op->reg2 == REG_PC)
2106 as_bad (_("Invalid destination register."));
2107
2108 byte = (op->reg1 << 4) | (op->reg2);
2109 if (format & M6812_OP_EXG_MARKER)
2110 byte |= 0x80;
2111
2112 f = frag_more (1);
2113 number_to_chars_bigendian (f, byte, 1);
2114 return 1;
2115}
2116
2117/* build_insn takes a pointer to the opcode entry in the opcode table,
2118 the array of operand expressions and builds the correspding instruction.
2119 This operation only deals with non relative jumps insn (need special
2120 handling). */
2121static void
2122build_insn (opcode, operands, nb_operands)
2123 struct m68hc11_opcode *opcode;
2124 operand operands[];
2125 int nb_operands ATTRIBUTE_UNUSED;
2126{
2127 int i;
2128 char *f;
2129 long format;
2130 int move_insn = 0;
2131
2132 /* Put the page code instruction if there is one. */
2133 format = opcode->format;
2134
2135 if (format & M6811_OP_BRANCH)
2136 fix_new (frag_now, frag_now_fix (), 1,
2137 &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
2138
2139 if (format & OP_EXTENDED)
2140 {
2141 int page_code;
2142
2143 f = m68hc11_new_insn (2);
2144 if (format & M6811_OP_PAGE2)
2145 page_code = M6811_OPCODE_PAGE2;
2146 else if (format & M6811_OP_PAGE3)
2147 page_code = M6811_OPCODE_PAGE3;
2148 else
2149 page_code = M6811_OPCODE_PAGE4;
2150
2151 number_to_chars_bigendian (f, page_code, 1);
2152 f++;
2153 }
2154 else
2155 f = m68hc11_new_insn (1);
2156
2157 number_to_chars_bigendian (f, opcode->opcode, 1);
2158
2159 i = 0;
2160
2161 /* The 68HC12 movb and movw instructions are special. We have to handle
2162 them in a special way. */
2163 if (format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2))
2164 {
2165 move_insn = 1;
2166 if (format & M6812_OP_IDX)
2167 {
2168 build_indexed_byte (&operands[0], format, 1);
2169 i = 1;
2170 format &= ~M6812_OP_IDX;
2171 }
2172 if (format & M6812_OP_IDX_P2)
2173 {
2174 build_indexed_byte (&operands[1], format, 1);
2175 i = 0;
2176 format &= ~M6812_OP_IDX_P2;
2177 }
2178 }
2179
2180 if (format & (M6811_OP_DIRECT | M6811_OP_IMM8))
2181 {
2182 fixup8 (&operands[i].exp,
2183 format & (M6811_OP_DIRECT | M6811_OP_IMM8 | M6812_OP_TRAP_ID),
2184 operands[i].mode);
2185 i++;
2186 }
2187 else if (IS_CALL_SYMBOL (format) && nb_operands == 1)
2188 {
2189 format &= ~M6812_OP_PAGE;
2190 fixup24 (&operands[i].exp, format & M6811_OP_IND16,
2191 operands[i].mode);
2192 i++;
2193 }
2194 else if (format & (M6811_OP_IMM16 | M6811_OP_IND16))
2195 {
2196 fixup16 (&operands[i].exp,
2197 format & (M6811_OP_IMM16 | M6811_OP_IND16 | M6812_OP_PAGE),
2198 operands[i].mode);
2199 i++;
2200 }
2201 else if (format & (M6811_OP_IX | M6811_OP_IY))
2202 {
2203 if ((format & M6811_OP_IX) && (operands[0].reg1 != REG_X))
2204 as_bad (_("Invalid indexed register, expecting register X."));
2205 if ((format & M6811_OP_IY) && (operands[0].reg1 != REG_Y))
2206 as_bad (_("Invalid indexed register, expecting register Y."));
2207
2208 fixup8 (&operands[0].exp, M6811_OP_IX, operands[0].mode);
2209 i = 1;
2210 }
2211 else if (format &
2212 (M6812_OP_IDX | M6812_OP_IDX_2 | M6812_OP_IDX_1
2213 | M6812_OP_D_IDX | M6812_OP_D_IDX_2))
2214 {
2215 build_indexed_byte (&operands[i], format, move_insn);
2216 i++;
2217 }
2218 else if (format & M6812_OP_REG && current_architecture & cpu6812)
2219 {
2220 build_reg_mode (&operands[i], format);
2221 i++;
2222 }
2223 if (format & M6811_OP_BITMASK)
2224 {
2225 fixup8 (&operands[i].exp, M6811_OP_BITMASK, operands[i].mode);
2226 i++;
2227 }
2228 if (format & M6811_OP_JUMP_REL)
2229 {
2230 fixup8 (&operands[i].exp, M6811_OP_JUMP_REL, operands[i].mode);
2231 }
2232 else if (format & M6812_OP_IND16_P2)
2233 {
2234 fixup16 (&operands[1].exp, M6811_OP_IND16, operands[1].mode);
2235 }
2236 if (format & M6812_OP_PAGE)
2237 {
2238 fixup8 (&operands[i].exp, M6812_OP_PAGE, operands[i].mode);
2239 }
2240}
2241
2242
2243/* Opcode identification and operand analysis. */
2244
2245/* find() gets a pointer to an entry in the opcode table. It must look at all
2246 opcodes with the same name and use the operands to choose the correct
2247 opcode. Returns the opcode pointer if there was a match and 0 if none. */
2248static struct m68hc11_opcode *
2249find (opc, operands, nb_operands)
2250 struct m68hc11_opcode_def *opc;
2251 operand operands[];
2252 int nb_operands;
2253{
2254 int i, match, pos;
2255 struct m68hc11_opcode *opcode;
2256 struct m68hc11_opcode *op_indirect;
2257
2258 op_indirect = 0;
2259 opcode = opc->opcode;
2260
2261 /* Now search the opcode table table for one with operands
2262 that matches what we've got. We're only done if the operands matched so
2263 far AND there are no more to check. */
2264 for (pos = match = 0; match == 0 && pos < opc->nb_modes; pos++, opcode++)
2265 {
2266 int poss_indirect = 0;
2267 long format = opcode->format;
2268 int expect;
2269
2270 expect = 0;
2271 if (opcode->format & M6811_OP_MASK)
2272 expect++;
2273 if (opcode->format & M6811_OP_BITMASK)
2274 expect++;
2275 if (opcode->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
2276 expect++;
2277 if (opcode->format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2))
2278 expect++;
2279 if ((opcode->format & M6812_OP_PAGE)
2280 && (!IS_CALL_SYMBOL (opcode->format) || nb_operands == 2))
2281 expect++;
2282
2283 for (i = 0; expect == nb_operands && i < nb_operands; i++)
2284 {
2285 int mode = operands[i].mode;
2286
2287 if (mode & M6811_OP_IMM16)
2288 {
2289 if (format &
2290 (M6811_OP_IMM8 | M6811_OP_IMM16 | M6811_OP_BITMASK))
2291 continue;
2292 break;
2293 }
2294 if (mode == M6811_OP_DIRECT)
2295 {
2296 if (format & M6811_OP_DIRECT)
2297 continue;
2298
2299 /* If the operand is a page 0 operand, remember a
2300 possible <abs-16> addressing mode. We mark
2301 this and continue to check other operands. */
2302 if (format & M6811_OP_IND16
2303 && flag_strict_direct_addressing && op_indirect == 0)
2304 {
2305 poss_indirect = 1;
2306 continue;
2307 }
2308 break;
2309 }
2310 if (mode & M6811_OP_IND16)
2311 {
2312 if (i == 0 && (format & M6811_OP_IND16) != 0)
2313 continue;
2314 if (i != 0 && (format & M6812_OP_PAGE) != 0)
2315 continue;
2316 if (i != 0 && (format & M6812_OP_IND16_P2) != 0)
2317 continue;
2318 if (i == 0 && (format & M6811_OP_BITMASK))
2319 break;
2320 }
2321 if (mode & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
2322 {
2323 if (format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
2324 continue;
2325 }
2326 if (mode & M6812_OP_REG)
2327 {
2328 if (i == 0
2329 && (format & M6812_OP_REG)
2330 && (operands[i].reg2 == REG_NONE))
2331 continue;
2332 if (i == 0
2333 && (format & M6812_OP_REG)
2334 && (format & M6812_OP_REG_2)
2335 && (operands[i].reg2 != REG_NONE))
2336 continue;
2337 if (i == 0
2338 && (format & M6812_OP_IDX)
2339 && (operands[i].reg2 != REG_NONE))
2340 continue;
2341 if (i == 0
2342 && (format & M6812_OP_IDX)
2343 && (format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2)))
2344 continue;
2345 if (i == 1
2346 && (format & M6812_OP_IDX_P2))
2347 continue;
2348 break;
2349 }
2350 if (mode & M6812_OP_IDX)
2351 {
2352 if (format & M6811_OP_IX && operands[i].reg1 == REG_X)
2353 continue;
2354 if (format & M6811_OP_IY && operands[i].reg1 == REG_Y)
2355 continue;
2356 if (i == 0
2357 && format & (M6812_OP_IDX | M6812_OP_IDX_1 | M6812_OP_IDX_2)
2358 && (operands[i].reg1 == REG_X
2359 || operands[i].reg1 == REG_Y
2360 || operands[i].reg1 == REG_SP
2361 || operands[i].reg1 == REG_PC))
2362 continue;
2363 if (i == 1 && format & M6812_OP_IDX_P2)
2364 continue;
2365 }
2366 if (mode & format & (M6812_OP_D_IDX | M6812_OP_D_IDX_2))
2367 {
2368 if (i == 0)
2369 continue;
2370 }
2371 if (mode & M6812_AUTO_INC_DEC)
2372 {
2373 if (i == 0
2374 && format & (M6812_OP_IDX | M6812_OP_IDX_1 |
2375 M6812_OP_IDX_2))
2376 continue;
2377 if (i == 1 && format & M6812_OP_IDX_P2)
2378 continue;
2379 }
2380 break;
2381 }
2382 match = i == nb_operands;
2383
2384 /* Operands are ok but an operand uses page 0 addressing mode
2385 while the insn supports abs-16 mode. Keep a reference to this
2386 insns in case there is no insn supporting page 0 addressing. */
2387 if (match && poss_indirect)
2388 {
2389 op_indirect = opcode;
2390 match = 0;
2391 }
2392 if (match)
2393 break;
2394 }
2395
2396 /* Page 0 addressing is used but not supported by any insn.
2397 If absolute addresses are supported, we use that insn. */
2398 if (match == 0 && op_indirect)
2399 {
2400 opcode = op_indirect;
2401 match = 1;
2402 }
2403
2404 if (!match)
2405 {
2406 return (0);
2407 }
2408
2409 return opcode;
2410}
2411
2412/* Find the real opcode and its associated operands. We use a progressive
2413 approach here. On entry, 'opc' points to the first opcode in the
2414 table that matches the opcode name in the source line. We try to
2415 isolate an operand, find a possible match in the opcode table.
2416 We isolate another operand if no match were found. The table 'operands'
2417 is filled while operands are recognized.
2418
2419 Returns the opcode pointer that matches the opcode name in the
2420 source line and the associated operands. */
2421static struct m68hc11_opcode *
2422find_opcode (opc, operands, nb_operands)
2423 struct m68hc11_opcode_def *opc;
2424 operand operands[];
2425 int *nb_operands;
2426{
2427 struct m68hc11_opcode *opcode;
2428 int i;
2429
2430 if (opc->max_operands == 0)
2431 {
2432 *nb_operands = 0;
2433 return opc->opcode;
2434 }
2435
2436 for (i = 0; i < opc->max_operands;)
2437 {
2438 int result;
2439
2440 result = get_operand (&operands[i], i, opc->format);
2441 if (result <= 0)
2442 return 0;
2443
2444 /* Special case where the bitmask of the bclr/brclr
2445 instructions is not introduced by #.
2446 Example: bclr 3,x $80. */
2447 if (i == 1 && (opc->format & M6811_OP_BITMASK)
2448 && (operands[i].mode & M6811_OP_IND16))
2449 {
2450 operands[i].mode = M6811_OP_IMM16;
2451 }
2452
2453 i += result;
2454 *nb_operands = i;
2455 if (i >= opc->min_operands)
2456 {
2457 opcode = find (opc, operands, i);
2458
2459 /* Another special case for 'call foo,page' instructions.
2460 Since we support 'call foo' and 'call foo,page' we must look
2461 if the optional page specification is present otherwise we will
2462 assemble immediately and treat the page spec as garbage. */
2463 if (opcode && !(opcode->format & M6812_OP_PAGE))
2464 return opcode;
2465
2466 if (opcode && *input_line_pointer != ',')
2467 return opcode;
2468 }
2469
2470 if (*input_line_pointer == ',')
2471 input_line_pointer++;
2472 }
2473
2474 return 0;
2475}
2476
2477#define M6812_XBCC_MARKER (M6812_OP_TBCC_MARKER \
2478 | M6812_OP_DBCC_MARKER \
2479 | M6812_OP_IBCC_MARKER)
2480
2481
2482/* Gas line assembler entry point. */
2483
2484/* This is the main entry point for the machine-dependent assembler. str
2485 points to a machine-dependent instruction. This function is supposed to
2486 emit the frags/bytes it assembles to. */
2487void
2488md_assemble (str)
2489 char *str;
2490{
2491 struct m68hc11_opcode_def *opc;
2492 struct m68hc11_opcode *opcode;
2493
2494 unsigned char *op_start, *save;
2495 unsigned char *op_end;
2496 char name[20];
2497 int nlen = 0;
2498 operand operands[M6811_MAX_OPERANDS];
2499 int nb_operands;
2500 int branch_optimize = 0;
2501 int alias_id = -1;
2502
2503 /* Drop leading whitespace. */
2504 while (*str == ' ')
2505 str++;
2506
2507 /* Find the opcode end and get the opcode in 'name'. The opcode is forced
2508 lower case (the opcode table only has lower case op-codes). */
2509 for (op_start = op_end = (unsigned char *) (str);
2510 *op_end && nlen < 20 && !is_end_of_line[*op_end] && *op_end != ' ';
2511 op_end++)
2512 {
2513 name[nlen] = TOLOWER (op_start[nlen]);
2514 nlen++;
2515 }
2516 name[nlen] = 0;
2517
2518 if (nlen == 0)
2519 {
2520 as_bad (_("No instruction or missing opcode."));
2521 return;
2522 }
2523
2524 /* Find the opcode definition given its name. */
2525 opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash, name);
2526
2527 /* If it's not recognized, look for 'jbsr' and 'jbxx'. These are
2528 pseudo insns for relative branch. For these branchs, we always
2529 optimize them (turned into absolute branchs) even if --short-branchs
2530 is given. */
2531 if (opc == NULL && name[0] == 'j' && name[1] == 'b')
2532 {
2533 opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash, &name[1]);
2534 if (opc
2535 && (!(opc->format & M6811_OP_JUMP_REL)
2536 || (opc->format & M6811_OP_BITMASK)))
2537 opc = 0;
2538 if (opc)
2539 branch_optimize = 1;
2540 }
2541
2542 /* The following test should probably be removed. This is not conform
2543 to Motorola assembler specs. */
2544 if (opc == NULL && flag_mri)
2545 {
2546 if (*op_end == ' ' || *op_end == '\t')
2547 {
2548 while (*op_end == ' ' || *op_end == '\t')
2549 op_end++;
2550
2551 if (nlen < 19
2552 && (*op_end &&
2553 (is_end_of_line[op_end[1]]
2554 || op_end[1] == ' ' || op_end[1] == '\t'
2555 || !ISALNUM (op_end[1])))
2556 && (*op_end == 'a' || *op_end == 'b'
2557 || *op_end == 'A' || *op_end == 'B'
2558 || *op_end == 'd' || *op_end == 'D'
2559 || *op_end == 'x' || *op_end == 'X'
2560 || *op_end == 'y' || *op_end == 'Y'))
2561 {
2562 name[nlen++] = TOLOWER (*op_end++);
2563 name[nlen] = 0;
2564 opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash,
2565 name);
2566 }
2567 }
2568 }
2569
2570 /* Identify a possible instruction alias. There are some on the
2571 68HC12 to emulate a few 68HC11 instructions. */
2572 if (opc == NULL && (current_architecture & cpu6812))
2573 {
2574 int i;
2575
2576 for (i = 0; i < m68hc12_num_alias; i++)
2577 if (strcmp (m68hc12_alias[i].name, name) == 0)
2578 {
2579 alias_id = i;
2580 break;
2581 }
2582 }
2583 if (opc == NULL && alias_id < 0)
2584 {
2585 as_bad (_("Opcode `%s' is not recognized."), name);
2586 return;
2587 }
2588 save = input_line_pointer;
2589 input_line_pointer = op_end;
2590
2591 if (opc)
2592 {
2593 opc->used++;
2594 opcode = find_opcode (opc, operands, &nb_operands);
2595 }
2596 else
2597 opcode = 0;
2598
2599 if ((opcode || alias_id >= 0) && !flag_mri)
2600 {
2601 char *p = input_line_pointer;
2602
2603 while (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r')
2604 p++;
2605
2606 if (*p != '\n' && *p)
2607 as_bad (_("Garbage at end of instruction: `%s'."), p);
2608 }
2609
2610 input_line_pointer = save;
2611
2612 if (alias_id >= 0)
2613 {
2614 char *f = m68hc11_new_insn (m68hc12_alias[alias_id].size);
2615
2616 number_to_chars_bigendian (f, m68hc12_alias[alias_id].code1, 1);
2617 if (m68hc12_alias[alias_id].size > 1)
2618 number_to_chars_bigendian (f + 1, m68hc12_alias[alias_id].code2, 1);
2619
2620 return;
2621 }
2622
2623 /* Opcode is known but does not have valid operands. Print out the
2624 syntax for this opcode. */
2625 if (opcode == 0)
2626 {
2627 if (flag_print_insn_syntax)
2628 print_insn_format (name);
2629
2630 as_bad (_("Invalid operand for `%s'"), name);
2631 return;
2632 }
2633
2634 /* Treat dbeq/ibeq/tbeq instructions in a special way. The branch is
2635 relative and must be in the range -256..255 (9-bits). */
2636 if ((opcode->format & M6812_XBCC_MARKER)
2637 && (opcode->format & M6811_OP_JUMP_REL))
2638 build_dbranch_insn (opcode, operands, nb_operands, branch_optimize);
2639
2640 /* Relative jumps instructions are taken care of separately. We have to make
2641 sure that the relative branch is within the range -128..127. If it's out
2642 of range, the instructions are changed into absolute instructions.
2643 This is not supported for the brset and brclr instructions. */
2644 else if ((opcode->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
2645 && !(opcode->format & M6811_OP_BITMASK))
2646 build_jump_insn (opcode, operands, nb_operands, branch_optimize);
2647 else
2648 build_insn (opcode, operands, nb_operands);
2649}
2650
2651
2652
2653/* Pseudo op to control the ELF flags. */
2654static void
2655s_m68hc11_mode (x)
2656 int x ATTRIBUTE_UNUSED;
2657{
2658 char *name = input_line_pointer, ch;
2659
2660 while (!is_end_of_line[(unsigned char) *input_line_pointer])
2661 input_line_pointer++;
2662 ch = *input_line_pointer;
2663 *input_line_pointer = '\0';
2664
2665 if (strcmp (name, "mshort") == 0)
2666 {
2667 elf_flags &= ~E_M68HC11_I32;
2668 }
2669 else if (strcmp (name, "mlong") == 0)
2670 {
2671 elf_flags |= E_M68HC11_I32;
2672 }
2673 else if (strcmp (name, "mshort-double") == 0)
2674 {
2675 elf_flags &= ~E_M68HC11_F64;
2676 }
2677 else if (strcmp (name, "mlong-double") == 0)
2678 {
2679 elf_flags |= E_M68HC11_F64;
2680 }
2681 else
2682 {
2683 as_warn (_("Invalid mode: %s\n"), name);
2684 }
2685 *input_line_pointer = ch;
2686 demand_empty_rest_of_line ();
2687}
2688
2689/* Mark the symbols with STO_M68HC12_FAR to indicate the functions
2690 are using 'rtc' for returning. It is necessary to use 'call'
2691 to invoke them. This is also used by the debugger to correctly
2692 find the stack frame. */
2693static void
2694s_m68hc11_mark_symbol (mark)
2695 int mark;
2696{
2697 char *name;
2698 int c;
2699 symbolS *symbolP;
2700 asymbol *bfdsym;
2701 elf_symbol_type *elfsym;
2702
2703 do
2704 {
2705 name = input_line_pointer;
2706 c = get_symbol_end ();
2707 symbolP = symbol_find_or_make (name);
2708 *input_line_pointer = c;
2709
2710 SKIP_WHITESPACE ();
2711
2712 bfdsym = symbol_get_bfdsym (symbolP);
2713 elfsym = elf_symbol_from (bfd_asymbol_bfd (bfdsym), bfdsym);
2714
2715 assert (elfsym);
2716
2717 /* Mark the symbol far (using rtc for function return). */
2718 elfsym->internal_elf_sym.st_other |= mark;
2719
2720 if (c == ',')
2721 {
2722 input_line_pointer ++;
2723
2724 SKIP_WHITESPACE ();
2725
2726 if (*input_line_pointer == '\n')
2727 c = '\n';
2728 }
2729 }
2730 while (c == ',');
2731
2732 demand_empty_rest_of_line ();
2733}
2734
2735static void
2736s_m68hc11_relax (ignore)
2737 int ignore ATTRIBUTE_UNUSED;
2738{
2739 expressionS ex;
2740
2741 expression (&ex);
2742
2743 if (ex.X_op != O_symbol || ex.X_add_number != 0)
2744 {
2745 as_bad (_("bad .relax format"));
2746 ignore_rest_of_line ();
2747 return;
2748 }
2749
2750 fix_new_exp (frag_now, frag_now_fix (), 1, &ex, 1,
2751 BFD_RELOC_M68HC11_RL_GROUP);
2752
2753 demand_empty_rest_of_line ();
2754}
2755
2756
2757
2758/* Relocation, relaxation and frag conversions. */
2759
2760/* PC-relative offsets are relative to the start of the
2761 next instruction. That is, the address of the offset, plus its
2762 size, since the offset is always the last part of the insn. */
2763long
2764md_pcrel_from (fixP)
2765 fixS *fixP;
2766{
2767 if (fixP->fx_r_type == BFD_RELOC_M68HC11_RL_JUMP)
2768 return 0;
2769
2770 return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
2771}
2772
2773/* If while processing a fixup, a reloc really needs to be created
2774 then it is done here. */
2775arelent *
2776tc_gen_reloc (section, fixp)
2777 asection *section ATTRIBUTE_UNUSED;
2778 fixS *fixp;
2779{
2780 arelent *reloc;
2781
2782 reloc = (arelent *) xmalloc (sizeof (arelent));
2783 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
2784 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
2785 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
2786 if (fixp->fx_r_type == 0)
2787 reloc->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_16);
2788 else
2789 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
2790 if (reloc->howto == (reloc_howto_type *) NULL)
2791 {
2792 as_bad_where (fixp->fx_file, fixp->fx_line,
2793 _("Relocation %d is not supported by object file format."),
2794 (int) fixp->fx_r_type);
2795 return NULL;
2796 }
2797
2798 /* Since we use Rel instead of Rela, encode the vtable entry to be
2799 used in the relocation's section offset. */
2800 if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
2801 reloc->address = fixp->fx_offset;
2802
2803 reloc->addend = 0;
2804 return reloc;
2805}
2806
2807/* We need a port-specific relaxation function to cope with sym2 - sym1
2808 relative expressions with both symbols in the same segment (but not
2809 necessarily in the same frag as this insn), for example:
2810 ldab sym2-(sym1-2),pc
2811 sym1:
2812 The offset can be 5, 9 or 16 bits long. */
2813
2814long
2815m68hc11_relax_frag (seg, fragP, stretch)
2816 segT seg ATTRIBUTE_UNUSED;
2817 fragS *fragP;
2818 long stretch ATTRIBUTE_UNUSED;
2819{
2820 long growth;
2821 offsetT aim = 0;
2822 symbolS *symbolP;
2823 const relax_typeS *this_type;
2824 const relax_typeS *start_type;
2825 relax_substateT next_state;
2826 relax_substateT this_state;
2827 const relax_typeS *table = TC_GENERIC_RELAX_TABLE;
2828
2829 /* We only have to cope with frags as prepared by
2830 md_estimate_size_before_relax. The STATE_BITS16 case may geet here
2831 because of the different reasons that it's not relaxable. */
2832 switch (fragP->fr_subtype)
2833 {
2834 case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS16):
2835 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16):
2836 /* When we get to this state, the frag won't grow any more. */
2837 return 0;
2838
2839 case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS5):
2840 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS5):
2841 case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS9):
2842 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9):
2843 if (fragP->fr_symbol == NULL
2844 || S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
2845 as_fatal (_("internal inconsistency problem in %s: fr_symbol %lx"),
2846 __FUNCTION__, (long) fragP->fr_symbol);
2847 symbolP = fragP->fr_symbol;
2848 if (symbol_resolved_p (symbolP))
2849 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
2850 __FUNCTION__);
2851 aim = S_GET_VALUE (symbolP);
2852 break;
2853
2854 default:
2855 as_fatal (_("internal inconsistency problem in %s: fr_subtype %d"),
2856 __FUNCTION__, fragP->fr_subtype);
2857 }
2858
2859 /* The rest is stolen from relax_frag. There's no obvious way to
2860 share the code, but fortunately no requirement to keep in sync as
2861 long as fragP->fr_symbol does not have its segment changed. */
2862
2863 this_state = fragP->fr_subtype;
2864 start_type = this_type = table + this_state;
2865
2866 if (aim < 0)
2867 {
2868 /* Look backwards. */
2869 for (next_state = this_type->rlx_more; next_state;)
2870 if (aim >= this_type->rlx_backward)
2871 next_state = 0;
2872 else
2873 {
2874 /* Grow to next state. */
2875 this_state = next_state;
2876 this_type = table + this_state;
2877 next_state = this_type->rlx_more;
2878 }
2879 }
2880 else
2881 {
2882 /* Look forwards. */
2883 for (next_state = this_type->rlx_more; next_state;)
2884 if (aim <= this_type->rlx_forward)
2885 next_state = 0;
2886 else
2887 {
2888 /* Grow to next state. */
2889 this_state = next_state;
2890 this_type = table + this_state;
2891 next_state = this_type->rlx_more;
2892 }
2893 }
2894
2895 growth = this_type->rlx_length - start_type->rlx_length;
2896 if (growth != 0)
2897 fragP->fr_subtype = this_state;
2898 return growth;
2899}
2900
2901void
2902md_convert_frag (abfd, sec, fragP)
2903 bfd *abfd ATTRIBUTE_UNUSED;
2904 asection *sec ATTRIBUTE_UNUSED;
2905 fragS *fragP;
2906{
2907 fixS *fixp;
2908 long value;
2909 long disp;
2910 char *buffer_address = fragP->fr_literal;
2911
2912 /* Address in object code of the displacement. */
2913 register int object_address = fragP->fr_fix + fragP->fr_address;
2914
2915 buffer_address += fragP->fr_fix;
2916
2917 /* The displacement of the address, from current location. */
2918 value = S_GET_VALUE (fragP->fr_symbol);
2919 disp = (value + fragP->fr_offset) - object_address;
2920
2921 switch (fragP->fr_subtype)
2922 {
2923 case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE):
2924 fragP->fr_opcode[1] = disp;
2925 break;
2926
2927 case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD):
2928 /* This relax is only for bsr and bra. */
2929 assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
2930 || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
2931 || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
2932
2933 fragP->fr_opcode[0] = convert_branch (fragP->fr_opcode[0]);
2934
2935 fix_new (fragP, fragP->fr_fix - 1, 2,
2936 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
2937 fragP->fr_fix += 1;
2938 break;
2939
2940 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_BYTE):
2941 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_BYTE):
2942 fragP->fr_opcode[1] = disp;
2943 break;
2944
2945 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_WORD):
2946 /* Invert branch. */
2947 fragP->fr_opcode[0] ^= 1;
2948 fragP->fr_opcode[1] = 3; /* Branch offset. */
2949 buffer_address[0] = M6811_JMP;
2950 fix_new (fragP, fragP->fr_fix + 1, 2,
2951 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
2952 fragP->fr_fix += 3;
2953 break;
2954
2955 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_WORD):
2956 /* Translate branch into a long branch. */
2957 fragP->fr_opcode[1] = fragP->fr_opcode[0];
2958 fragP->fr_opcode[0] = M6811_OPCODE_PAGE2;
2959
2960 fixp = fix_new (fragP, fragP->fr_fix, 2,
2961 fragP->fr_symbol, fragP->fr_offset, 1,
2962 BFD_RELOC_16_PCREL);
2963 fixp->fx_pcrel_adjust = 2;
2964 fragP->fr_fix += 2;
2965 break;
2966
2967 case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS5):
2968 if (fragP->fr_symbol != 0
2969 && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
2970 value = disp;
2971 /* fall through */
2972
2973 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS5):
2974 fragP->fr_opcode[0] = fragP->fr_opcode[0] << 6;
2975 fragP->fr_opcode[0] |= value & 0x1f;
2976 break;
2977
2978 case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS9):
2979 /* For a PC-relative offset, use the displacement with a -1 correction
2980 to take into account the additional byte of the insn. */
2981 if (fragP->fr_symbol != 0
2982 && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
2983 value = disp - 1;
2984 /* fall through */
2985
2986 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9):
2987 fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3);
2988 fragP->fr_opcode[0] |= 0xE0;
2989 fragP->fr_opcode[0] |= (value >> 8) & 1;
2990 fragP->fr_opcode[1] = value;
2991 fragP->fr_fix += 1;
2992 break;
2993
2994 case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS16):
2995 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16):
2996 fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3);
2997 fragP->fr_opcode[0] |= 0xe2;
2998 if ((fragP->fr_opcode[0] & 0x0ff) == 0x0fa
2999 && fragP->fr_symbol != 0
3000 && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
3001 {
3002 fixp = fix_new (fragP, fragP->fr_fix, 2,
3003 fragP->fr_symbol, fragP->fr_offset,
3004 1, BFD_RELOC_16_PCREL);
3005 }
3006 else
3007 {
3008 fix_new (fragP, fragP->fr_fix, 2,
3009 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
3010 }
3011 fragP->fr_fix += 2;
3012 break;
3013
3014 case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_BYTE):
3015 if (disp < 0)
3016 fragP->fr_opcode[0] |= 0x10;
3017
3018 fragP->fr_opcode[1] = disp & 0x0FF;
3019 break;
3020
3021 case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_WORD):
3022 /* Invert branch. */
3023 fragP->fr_opcode[0] ^= 0x20;
3024 fragP->fr_opcode[1] = 3; /* Branch offset. */
3025 buffer_address[0] = M6812_JMP;
3026 fix_new (fragP, fragP->fr_fix + 1, 2,
3027 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
3028 fragP->fr_fix += 3;
3029 break;
3030
3031 default:
3032 break;
3033 }
3034}
3035
3036/* On an ELF system, we can't relax a weak symbol. The weak symbol
3037 can be overridden at final link time by a non weak symbol. We can
3038 relax externally visible symbol because there is no shared library
3039 and such symbol can't be overridden (unless they are weak). */
3040static int
3041relaxable_symbol (symbol)
3042 symbolS *symbol;
3043{
3044 return ! S_IS_WEAK (symbol);
3045}
3046
3047/* Force truly undefined symbols to their maximum size, and generally set up
3048 the frag list to be relaxed. */
3049int
3050md_estimate_size_before_relax (fragP, segment)
3051 fragS *fragP;
3052 asection *segment;
3053{
3054 if (RELAX_LENGTH (fragP->fr_subtype) == STATE_UNDF)
3055 {
3056 if (S_GET_SEGMENT (fragP->fr_symbol) != segment
3057 || !relaxable_symbol (fragP->fr_symbol)
3058 || (segment != absolute_section
3059 && RELAX_STATE (fragP->fr_subtype) == STATE_INDEXED_OFFSET))
3060 {
3061 /* Non-relaxable cases. */
3062 int old_fr_fix;
3063 char *buffer_address;
3064
3065 old_fr_fix = fragP->fr_fix;
3066 buffer_address = fragP->fr_fix + fragP->fr_literal;
3067
3068 switch (RELAX_STATE (fragP->fr_subtype))
3069 {
3070 case STATE_PC_RELATIVE:
3071
3072 /* This relax is only for bsr and bra. */
3073 assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
3074 || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
3075 || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
3076
3077 if (flag_fixed_branchs)
3078 as_bad_where (fragP->fr_file, fragP->fr_line,
3079 _("bra or bsr with undefined symbol."));
3080
3081 /* The symbol is undefined or in a separate section.
3082 Turn bra into a jmp and bsr into a jsr. The insn
3083 becomes 3 bytes long (instead of 2). A fixup is
3084 necessary for the unresolved symbol address. */
3085 fragP->fr_opcode[0] = convert_branch (fragP->fr_opcode[0]);
3086
3087 fix_new (fragP, fragP->fr_fix - 1, 2, fragP->fr_symbol,
3088 fragP->fr_offset, 0, BFD_RELOC_16);
3089 fragP->fr_fix++;
3090 break;
3091
3092 case STATE_CONDITIONAL_BRANCH:
3093 assert (current_architecture & cpu6811);
3094
3095 fragP->fr_opcode[0] ^= 1; /* Reverse sense of branch. */
3096 fragP->fr_opcode[1] = 3; /* Skip next jmp insn (3 bytes). */
3097
3098 /* Don't use fr_opcode[2] because this may be
3099 in a different frag. */
3100 buffer_address[0] = M6811_JMP;
3101
3102 fragP->fr_fix++;
3103 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
3104 fragP->fr_offset, 0, BFD_RELOC_16);
3105 fragP->fr_fix += 2;
3106 break;
3107
3108 case STATE_INDEXED_OFFSET:
3109 assert (current_architecture & cpu6812);
3110
3111 if (fragP->fr_symbol
3112 && S_GET_SEGMENT (fragP->fr_symbol) == absolute_section)
3113 {
3114 fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_OFFSET,
3115 STATE_BITS5);
3116 /* Return the size of the variable part of the frag. */
3117 return md_relax_table[fragP->fr_subtype].rlx_length;
3118 }
3119 else
3120 {
3121 /* Switch the indexed operation to 16-bit mode. */
3122 fragP->fr_opcode[0] = fragP->fr_opcode[0] << 3;
3123 fragP->fr_opcode[0] |= 0xe2;
3124 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
3125 fragP->fr_offset, 0, BFD_RELOC_16);
3126 fragP->fr_fix += 2;
3127 }
3128 break;
3129
3130 case STATE_INDEXED_PCREL:
3131 assert (current_architecture & cpu6812);
3132
3133 if (fragP->fr_symbol
3134 && S_GET_SEGMENT (fragP->fr_symbol) == absolute_section)
3135 {
3136 fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_PCREL,
3137 STATE_BITS5);
3138 /* Return the size of the variable part of the frag. */
3139 return md_relax_table[fragP->fr_subtype].rlx_length;
3140 }
3141 else
3142 {
3143 fixS* fixp;
3144
3145 fragP->fr_opcode[0] = fragP->fr_opcode[0] << 3;
3146 fragP->fr_opcode[0] |= 0xe2;
3147 fixp = fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
3148 fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
3149 fragP->fr_fix += 2;
3150 }
3151 break;
3152
3153 case STATE_XBCC_BRANCH:
3154 assert (current_architecture & cpu6812);
3155
3156 fragP->fr_opcode[0] ^= 0x20; /* Reverse sense of branch. */
3157 fragP->fr_opcode[1] = 3; /* Skip next jmp insn (3 bytes). */
3158
3159 /* Don't use fr_opcode[2] because this may be
3160 in a different frag. */
3161 buffer_address[0] = M6812_JMP;
3162
3163 fragP->fr_fix++;
3164 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
3165 fragP->fr_offset, 0, BFD_RELOC_16);
3166 fragP->fr_fix += 2;
3167 break;
3168
3169 case STATE_CONDITIONAL_BRANCH_6812:
3170 assert (current_architecture & cpu6812);
3171
3172 /* Translate into a lbcc branch. */
3173 fragP->fr_opcode[1] = fragP->fr_opcode[0];
3174 fragP->fr_opcode[0] = M6811_OPCODE_PAGE2;
3175
3176 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
3177 fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
3178 fragP->fr_fix += 2;
3179 break;
3180
3181 default:
3182 as_fatal (_("Subtype %d is not recognized."), fragP->fr_subtype);
3183 }
3184 frag_wane (fragP);
3185
3186 /* Return the growth in the fixed part of the frag. */
3187 return fragP->fr_fix - old_fr_fix;
3188 }
3189
3190 /* Relaxable cases. */
3191 switch (RELAX_STATE (fragP->fr_subtype))
3192 {
3193 case STATE_PC_RELATIVE:
3194 /* This relax is only for bsr and bra. */
3195 assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
3196 || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
3197 || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
3198
3199 fragP->fr_subtype = ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE);
3200 break;
3201
3202 case STATE_CONDITIONAL_BRANCH:
3203 assert (current_architecture & cpu6811);
3204
3205 fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH,
3206 STATE_BYTE);
3207 break;
3208
3209 case STATE_INDEXED_OFFSET:
3210 assert (current_architecture & cpu6812);
3211
3212 fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_OFFSET,
3213 STATE_BITS5);
3214 break;
3215
3216 case STATE_INDEXED_PCREL:
3217 assert (current_architecture & cpu6812);
3218
3219 fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_PCREL,
3220 STATE_BITS5);
3221 break;
3222
3223 case STATE_XBCC_BRANCH:
3224 assert (current_architecture & cpu6812);
3225
3226 fragP->fr_subtype = ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_BYTE);
3227 break;
3228
3229 case STATE_CONDITIONAL_BRANCH_6812:
3230 assert (current_architecture & cpu6812);
3231
3232 fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812,
3233 STATE_BYTE);
3234 break;
3235 }
3236 }
3237
3238 if (fragP->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))
3239 as_fatal (_("Subtype %d is not recognized."), fragP->fr_subtype);
3240
3241 /* Return the size of the variable part of the frag. */
3242 return md_relax_table[fragP->fr_subtype].rlx_length;
3243}
3244
3245/* See whether we need to force a relocation into the output file. */
3246int
3247tc_m68hc11_force_relocation (fixP)
3248 fixS * fixP;
3249{
3250 if (fixP->fx_r_type == BFD_RELOC_M68HC11_RL_GROUP)
3251 return 1;
3252
3253 return generic_force_reloc (fixP);
3254}
3255
3256/* Here we decide which fixups can be adjusted to make them relative
3257 to the beginning of the section instead of the symbol. Basically
3258 we need to make sure that the linker relaxation is done
3259 correctly, so in some cases we force the original symbol to be
3260 used. */
3261int
3262tc_m68hc11_fix_adjustable (fixP)
3263 fixS *fixP;
3264{
3265 switch (fixP->fx_r_type)
3266 {
3267 /* For the linker relaxation to work correctly, these relocs
3268 need to be on the symbol itself. */
3269 case BFD_RELOC_16:
3270 case BFD_RELOC_M68HC11_RL_JUMP:
3271 case BFD_RELOC_M68HC11_RL_GROUP:
3272 case BFD_RELOC_VTABLE_INHERIT:
3273 case BFD_RELOC_VTABLE_ENTRY:
3274 case BFD_RELOC_32:
3275
3276 /* The memory bank addressing translation also needs the original
3277 symbol. */
3278 case BFD_RELOC_M68HC11_LO16:
3279 case BFD_RELOC_M68HC11_PAGE:
3280 case BFD_RELOC_M68HC11_24:
3281 return 0;
3282
3283 default:
3284 return 1;
3285 }
3286}
3287
3288void
3289md_apply_fix3 (fixP, valP, seg)
3290 fixS *fixP;
3291 valueT *valP;
3292 segT seg ATTRIBUTE_UNUSED;
3293{
3294 char *where;
3295 long value = * valP;
3296 int op_type;
3297
3298 if (fixP->fx_addsy == (symbolS *) NULL)
3299 fixP->fx_done = 1;
3300
3301 /* We don't actually support subtracting a symbol. */
3302 if (fixP->fx_subsy != (symbolS *) NULL)
3303 as_bad_where (fixP->fx_file, fixP->fx_line, _("Expression too complex."));
3304
3305 op_type = fixP->fx_r_type;
3306
3307 /* Patch the instruction with the resolved operand. Elf relocation
3308 info will also be generated to take care of linker/loader fixups.
3309 The 68HC11 addresses only 64Kb, we are only concerned by 8 and 16-bit
3310 relocs. BFD_RELOC_8 is basically used for .page0 access (the linker
3311 will warn for overflows). BFD_RELOC_8_PCREL should not be generated
3312 because it's either resolved or turned out into non-relative insns (see
3313 relax table, bcc, bra, bsr transformations)
3314
3315 The BFD_RELOC_32 is necessary for the support of --gstabs. */
3316 where = fixP->fx_frag->fr_literal + fixP->fx_where;
3317
3318 switch (fixP->fx_r_type)
3319 {
3320 case BFD_RELOC_32:
3321 bfd_putb32 ((bfd_vma) value, (unsigned char *) where);
3322 break;
3323
3324 case BFD_RELOC_24:
3325 case BFD_RELOC_M68HC11_24:
3326 bfd_putb16 ((bfd_vma) (value & 0x0ffff), (unsigned char *) where);
3327 ((bfd_byte*) where)[2] = ((value >> 16) & 0x0ff);
3328 break;
3329
3330 case BFD_RELOC_16:
3331 case BFD_RELOC_16_PCREL:
3332 case BFD_RELOC_M68HC11_LO16:
3333 bfd_putb16 ((bfd_vma) value, (unsigned char *) where);
3334 if (value < -65537 || value > 65535)
3335 as_bad_where (fixP->fx_file, fixP->fx_line,
3336 _("Value out of 16-bit range."));
3337 break;
3338
3339 case BFD_RELOC_M68HC11_HI8:
3340 value = value >> 8;
3341 /* Fall through. */
3342
3343 case BFD_RELOC_M68HC11_LO8:
3344 case BFD_RELOC_8:
3345 case BFD_RELOC_M68HC11_PAGE:
3346#if 0
3347 bfd_putb8 ((bfd_vma) value, (unsigned char *) where);
3348#endif
3349 ((bfd_byte *) where)[0] = (bfd_byte) value;
3350 break;
3351
3352 case BFD_RELOC_8_PCREL:
3353#if 0
3354 bfd_putb8 ((bfd_vma) value, (unsigned char *) where);
3355#endif
3356 ((bfd_byte *) where)[0] = (bfd_byte) value;
3357
3358 if (value < -128 || value > 127)
3359 as_bad_where (fixP->fx_file, fixP->fx_line,
3360 _("Value %ld too large for 8-bit PC-relative branch."),
3361 value);
3362 break;
3363
3364 case BFD_RELOC_M68HC11_3B:
3365 if (value <= 0 || value > 8)
3366 as_bad_where (fixP->fx_file, fixP->fx_line,
3367 _("Auto increment/decrement offset '%ld' is out of range."),
3368 value);
3369 if (where[0] & 0x8)
3370 value = 8 - value;
3371 else
3372 value--;
3373
3374 where[0] = where[0] | (value & 0x07);
3375 break;
3376
3377 case BFD_RELOC_M68HC11_RL_JUMP:
3378 case BFD_RELOC_M68HC11_RL_GROUP:
3379 case BFD_RELOC_VTABLE_INHERIT:
3380 case BFD_RELOC_VTABLE_ENTRY:
3381 fixP->fx_done = 0;
3382 return;
3383
3384 default:
3385 as_fatal (_("Line %d: unknown relocation type: 0x%x."),
3386 fixP->fx_line, fixP->fx_r_type);
3387 }
3388}
3389
3390/* Set the ELF specific flags. */
3391void
3392m68hc11_elf_final_processing ()
3393{
3394 if (current_architecture & cpu6812s)
3395 elf_flags |= EF_M68HCS12_MACH;
3396 elf_elfheader (stdoutput)->e_flags &= ~EF_M68HC11_ABI;
3397 elf_elfheader (stdoutput)->e_flags |= elf_flags;
3398}
Note: See TracBrowser for help on using the repository browser.