]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gas/config/tc-m68hc11.c
* readelf.c (display_debug_lines): Fix section length check
[thirdparty/binutils-gdb.git] / gas / config / tc-m68hc11.c
CommitLineData
60bcf0fa
NC
1/* tc-m68hc11.c -- Assembler code for the Motorola 68HC11 & 68HC12.
2 Copyright (C) 1999, 2000 Free Software Foundation.
3 Written by Stephane Carrez (stcarrez@worldnet.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 <stdio.h>
23#include <ctype.h>
24#include "as.h"
25#include "subsegs.h"
26#include "opcode/m68hc11.h"
27#include "dwarf2dbg.h"
28
60bcf0fa
NC
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_XBCC_BRANCH (4)
40#define STATE_CONDITIONAL_BRANCH_6812 (5)
41
42#define STATE_BYTE (0)
43#define STATE_BITS5 (0)
44#define STATE_WORD (1)
45#define STATE_BITS9 (1)
46#define STATE_LONG (2)
47#define STATE_BITS16 (2)
48#define STATE_UNDF (3) /* Symbol undefined in pass1 */
49
50/* This macro has no side-effects. */
51#define ENCODE_RELAX(what,length) (((what) << 2) + (length))
52
53#define IS_OPCODE(C1,C2) (((C1) & 0x0FF) == ((C2) & 0x0FF))
54
55/* This table describes how you change sizes for the various types of variable
56 size expressions. This version only supports two kinds. */
57
58/* The fields are:
fafb6d17
NC
59 How far Forward this mode will reach.
60 How far Backward this mode will reach.
61 How many bytes this mode will add to the size of the frag.
62 Which mode to go to if the offset won't fit in this one. */
63
64relax_typeS md_relax_table[] =
65{
66 {1, 1, 0, 0}, /* First entries aren't used. */
67 {1, 1, 0, 0}, /* For no good reason except. */
68 {1, 1, 0, 0}, /* that the VAX doesn't either. */
60bcf0fa
NC
69 {1, 1, 0, 0},
70
71 /* Relax for bcc <L>.
72 These insns are translated into b!cc +3 jmp L. */
73 {(127), (-128), 0, ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_WORD)},
74 {0, 0, 3, 0},
75 {1, 1, 0, 0},
76 {1, 1, 0, 0},
77
78 /* Relax for bsr <L> and bra <L>.
79 These insns are translated into jsr and jmp. */
80 {(127), (-128), 0, ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD)},
81 {0, 0, 1, 0},
82 {1, 1, 0, 0},
83 {1, 1, 0, 0},
84
85 /* Relax for indexed offset: 5-bits, 9-bits, 16-bits. */
86 {(15), (-16), 0, ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9)},
87 {(255), (-256), 1, ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16)},
88 {0, 0, 1, 0},
89 {1, 1, 0, 0},
90
91 /* Relax for dbeq/ibeq/tbeq r,<L>:
92 These insns are translated into db!cc +3 jmp L. */
93 {(255), (-256), 0, ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_WORD)},
94 {0, 0, 3, 0},
95 {1, 1, 0, 0},
96 {1, 1, 0, 0},
97
98 /* Relax for bcc <L> on 68HC12.
99 These insns are translated into lbcc <L>. */
100 {(127), (-128), 0, ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_WORD)},
101 {0, 0, 2, 0},
102 {1, 1, 0, 0},
103 {1, 1, 0, 0},
104
105};
106
107/* 68HC11 and 68HC12 registers. They are numbered according to the 68HC12. */
108typedef enum register_id
109{
110 REG_NONE = -1,
111 REG_A = 0,
112 REG_B = 1,
113 REG_CCR = 2,
114 REG_D = 4,
115 REG_X = 5,
116 REG_Y = 6,
117 REG_SP = 7,
118 REG_PC = 8
119} register_id;
120
121typedef struct operand
122{
123 expressionS exp;
124 register_id reg1;
125 register_id reg2;
126 int mode;
127} operand;
128
129struct m68hc11_opcode_def
130{
131 long format;
132 int min_operands;
133 int max_operands;
134 int nb_modes;
135 int used;
136 struct m68hc11_opcode *opcode;
137};
138
139static struct m68hc11_opcode_def *m68hc11_opcode_defs = 0;
140static int m68hc11_nb_opcode_defs = 0;
141
142typedef struct alias
143{
144 const char *name;
145 const char *alias;
146}
147alias;
148
fafb6d17
NC
149static alias alias_opcodes[] =
150{
60bcf0fa
NC
151 {"cpd", "cmpd"},
152 {"cpx", "cmpx"},
153 {"cpy", "cmpy"},
154 {0, 0}
155};
156
fafb6d17
NC
157/* Local functions. */
158static register_id reg_name_search PARAMS ((char *));
159static register_id register_name PARAMS ((void));
160static int check_range PARAMS ((long, int));
60bcf0fa 161static void print_opcode_list PARAMS ((void));
60bcf0fa 162static void get_default_target PARAMS ((void));
fafb6d17
NC
163static void print_insn_format PARAMS ((char *));
164static int get_operand PARAMS ((operand *, int, long));
165static void fixup8 PARAMS ((expressionS *, int, int));
166static void fixup16 PARAMS ((expressionS *, int, int));
60bcf0fa 167static struct m68hc11_opcode *find_opcode
fafb6d17 168 PARAMS ((struct m68hc11_opcode_def *, operand *, int *));
60bcf0fa 169static void build_jump_insn
fafb6d17
NC
170 PARAMS ((struct m68hc11_opcode *, operand *, int, int));
171static void build_insn
172 PARAMS ((struct m68hc11_opcode *, operand *, int));
60bcf0fa
NC
173
174/* Controls whether relative branches can be turned into long branches.
175 When the relative offset is too large, the insn are changed:
176 bra -> jmp
177 bsr -> jsr
178 bcc -> b!cc +3
179 jmp L
180 dbcc -> db!cc +3
181 jmp L
fafb6d17 182
60bcf0fa
NC
183 Setting the flag forbidds this. */
184static short flag_fixed_branchs = 0;
185
186/* Force to use long jumps (absolute) instead of relative branches. */
187static short flag_force_long_jumps = 0;
188
189/* Change the direct addressing mode into an absolute addressing mode
190 when the insn does not support direct addressing.
191 For example, "clr *ZD0" is normally not possible and is changed
192 into "clr ZDO". */
193static short flag_strict_direct_addressing = 1;
194
195/* When an opcode has invalid operand, print out the syntax of the opcode
196 to stderr. */
197static short flag_print_insn_syntax = 0;
198
199/* Dumps the list of instructions with syntax and then exit:
200 1 -> Only dumps the list (sorted by name)
201 2 -> Generate an example (or test) that can be compiled. */
202static short flag_print_opcodes = 0;
203
204/* Opcode hash table. */
205static struct hash_control *m68hc11_hash;
206
207/* Current cpu (either cpu6811 or cpu6812). This is determined automagically
208 by 'get_default_target' by looking at default BFD vector. This is overriden
209 with the -m<cpu> option. */
210static int current_architecture = 0;
211
212/* Default cpu determined by 'get_default_target'. */
213static const char *default_cpu;
214
215/* Number of opcodes in the sorted table (filtered by current cpu). */
216static int num_opcodes;
217
218/* The opcodes sorted by name and filtered by current cpu. */
219static struct m68hc11_opcode *m68hc11_sorted_opcodes;
220
221/* These are the machine dependent pseudo-ops. These are included so
222 the assembler can work on the output from the SUN C compiler, which
223 generates these. */
224
225/* This table describes all the machine specific pseudo-ops the assembler
226 has to support. The fields are:
227 pseudo-op name without dot
228 function to call to execute this pseudo-op
229 Integer arg to pass to the function. */
fafb6d17
NC
230const pseudo_typeS md_pseudo_table[] =
231{
60bcf0fa
NC
232 /* The following pseudo-ops are supported for MRI compatibility. */
233 {"fcb", cons, 1},
234 {"fdb", cons, 2},
235 {"fcc", stringer, 1},
236 {"rmb", s_space, 0},
237 {"file", dwarf2_directive_file, 0},
238 {"loc", dwarf2_directive_loc, 0},
239
240 {0, 0, 0}
241};
60bcf0fa
NC
242\f
243/* Options and initialization. */
244
245CONST char *md_shortopts = "Sm:";
246
fafb6d17
NC
247struct option md_longopts[] =
248{
60bcf0fa
NC
249#define OPTION_FORCE_LONG_BRANCH (OPTION_MD_BASE)
250 {"force-long-branchs", no_argument, NULL, OPTION_FORCE_LONG_BRANCH},
251
252#define OPTION_SHORT_BRANCHS (OPTION_MD_BASE + 1)
253 {"short-branchs", no_argument, NULL, OPTION_SHORT_BRANCHS},
254
255#define OPTION_STRICT_DIRECT_MODE (OPTION_MD_BASE + 2)
256 {"strict-direct-mode", no_argument, NULL, OPTION_STRICT_DIRECT_MODE},
257
258#define OPTION_PRINT_INSN_SYNTAX (OPTION_MD_BASE + 3)
259 {"print-insn-syntax", no_argument, NULL, OPTION_PRINT_INSN_SYNTAX},
260
261#define OPTION_PRINT_OPCODES (OPTION_MD_BASE + 4)
262 {"print-opcodes", no_argument, NULL, OPTION_PRINT_OPCODES},
263
264#define OPTION_GENERATE_EXAMPLE (OPTION_MD_BASE + 5)
265 {"generate-example", no_argument, NULL, OPTION_GENERATE_EXAMPLE},
266
267 {NULL, no_argument, NULL, 0}
268};
269size_t md_longopts_size = sizeof (md_longopts);
270
271/* Get the target cpu for the assembler. This is based on the configure
272 options and on the -m68hc11/-m68hc12 option. If no option is specified,
273 we must get the default. */
274const char *
275m68hc11_arch_format ()
276{
277 get_default_target ();
278 if (current_architecture & cpu6811)
279 return "elf32-m68hc11";
280 else
281 return "elf32-m68hc12";
282}
283
284enum bfd_architecture
285m68hc11_arch ()
286{
287 get_default_target ();
288 if (current_architecture & cpu6811)
289 return bfd_arch_m68hc11;
290 else
291 return bfd_arch_m68hc12;
292}
293
294int
295m68hc11_mach ()
296{
297 return 0;
298}
299
60bcf0fa
NC
300void
301md_show_usage (stream)
302 FILE *stream;
303{
304 get_default_target ();
305 fprintf (stream, _("\
306Motorola 68HC11/68HC12 options:\n\
307 -m68hc11 | -m68hc12 specify the processor [default %s]\n\
308 --force-long-branchs always turn relative branchs into absolute ones\n\
309 -S,--short-branchs do not turn relative branchs into absolute ones\n\
310 when the offset is out of range\n\
311 --strict-direct-mode do not turn the direct mode into extended mode\n\
312 when the instruction does not support direct mode\n\
313 --print-insn-syntax print the syntax of instruction in case of error\n\
314 --print-opcodes print the list of instructions with syntax\n\
315 --generate-example generate an example of each instruction\n\
316 (used for testing)\n"), default_cpu);
317
318}
319
320/* Try to identify the default target based on the BFD library. */
321static void
322get_default_target ()
323{
324 const bfd_target *target;
325 bfd abfd;
326
327 if (current_architecture != 0)
328 return;
329
330 default_cpu = "unknown";
331 target = bfd_find_target (0, &abfd);
332 if (target && target->name)
333 {
334 if (strcmp (target->name, "elf32-m68hc12") == 0)
335 {
336 current_architecture = cpu6812;
337 default_cpu = "m68hc12";
338 }
339 else if (strcmp (target->name, "elf32-m68hc11") == 0)
340 {
341 current_architecture = cpu6811;
342 default_cpu = "m68hc11";
343 }
344 else
345 {
346 as_bad (_("Default target `%s' is not supported."), target->name);
347 }
348 }
349}
350
351void
352m68hc11_print_statistics (file)
353 FILE *file;
354{
355 int i;
356 struct m68hc11_opcode_def *opc;
357
358 hash_print_statistics (file, "opcode table", m68hc11_hash);
359
360 opc = m68hc11_opcode_defs;
361 if (opc == 0 || m68hc11_nb_opcode_defs == 0)
362 return;
363
364 /* Dump the opcode statistics table. */
365 fprintf (file, _("Name # Modes Min ops Max ops Modes mask # Used\n"));
366 for (i = 0; i < m68hc11_nb_opcode_defs; i++, opc++)
367 {
368 fprintf (file, "%-7.7s %5d %7d %7d 0x%08lx %7d\n",
369 opc->opcode->name,
370 opc->nb_modes,
371 opc->min_operands, opc->max_operands, opc->format, opc->used);
372 }
373}
374
375int
376md_parse_option (c, arg)
377 int c;
378 char *arg;
379{
380 get_default_target ();
381 switch (c)
382 {
383 /* -S means keep external to 2 bits offset rather than 16 bits one. */
384 case OPTION_SHORT_BRANCHS:
385 case 'S':
386 flag_fixed_branchs = 1;
387 break;
388
389 case OPTION_FORCE_LONG_BRANCH:
390 flag_force_long_jumps = 1;
391 break;
392
393 case OPTION_PRINT_INSN_SYNTAX:
394 flag_print_insn_syntax = 1;
395 break;
396
397 case OPTION_PRINT_OPCODES:
398 flag_print_opcodes = 1;
399 break;
400
401 case OPTION_STRICT_DIRECT_MODE:
402 flag_strict_direct_addressing = 0;
403 break;
404
405 case OPTION_GENERATE_EXAMPLE:
406 flag_print_opcodes = 2;
407 break;
408
409 case 'm':
410 if (strcasecmp (arg, "68hc11") == 0)
411 current_architecture = cpu6811;
412 else if (strcasecmp (arg, "68hc12") == 0)
413 current_architecture = cpu6812;
414 else
415 as_bad (_("Option `%s' is not recognized."), arg);
416 break;
417
418 default:
419 return 0;
420 }
421
422 return 1;
423}
424\f
425symbolS *
426md_undefined_symbol (name)
427 char *name ATTRIBUTE_UNUSED;
428{
429 return 0;
430}
431
fafb6d17 432/* Equal to MAX_PRECISION in atof-ieee.c. */
60bcf0fa
NC
433#define MAX_LITTLENUMS 6
434
435/* Turn a string in input_line_pointer into a floating point constant
bc0d738a
NC
436 of type TYPE, and store the appropriate bytes in *LITP. The number
437 of LITTLENUMS emitted is stored in *SIZEP. An error message is
60bcf0fa 438 returned, or NULL on OK. */
60bcf0fa
NC
439char *
440md_atof (type, litP, sizeP)
441 char type;
442 char *litP;
443 int *sizeP;
444{
445 int prec;
446 LITTLENUM_TYPE words[MAX_LITTLENUMS];
447 LITTLENUM_TYPE *wordP;
448 char *t;
449
450 switch (type)
451 {
452 case 'f':
453 case 'F':
454 case 's':
455 case 'S':
456 prec = 2;
457 break;
458
459 case 'd':
460 case 'D':
461 case 'r':
462 case 'R':
463 prec = 4;
464 break;
465
466 case 'x':
467 case 'X':
468 prec = 6;
469 break;
470
471 case 'p':
472 case 'P':
473 prec = 6;
474 break;
475
476 default:
477 *sizeP = 0;
478 return _("Bad call to MD_ATOF()");
479 }
480 t = atof_ieee (input_line_pointer, type, words);
481 if (t)
482 input_line_pointer = t;
483
484 *sizeP = prec * sizeof (LITTLENUM_TYPE);
485 for (wordP = words; prec--;)
486 {
487 md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE));
488 litP += sizeof (LITTLENUM_TYPE);
489 }
490 return 0;
491}
492
493valueT
494md_section_align (seg, addr)
495 asection *seg;
496 valueT addr;
497{
498 int align = bfd_get_section_alignment (stdoutput, seg);
499 return ((addr + (1 << align) - 1) & (-1 << align));
500}
501
60bcf0fa
NC
502static int
503cmp_opcode (op1, op2)
504 struct m68hc11_opcode *op1;
505 struct m68hc11_opcode *op2;
506{
507 return strcmp (op1->name, op2->name);
508}
509
510/* Initialize the assembler. Create the opcode hash table
511 (sorted on the names) with the M6811 opcode table
512 (from opcode library). */
513void
514md_begin ()
515{
516 char *prev_name = "";
517 struct m68hc11_opcode *opcodes;
518 struct m68hc11_opcode_def *opc = 0;
519 int i, j;
520
521 get_default_target ();
522
523 m68hc11_hash = hash_new ();
524
525 /* Get a writable copy of the opcode table and sort it on the names. */
526 opcodes = (struct m68hc11_opcode *) xmalloc (m68hc11_num_opcodes *
527 sizeof (struct
528 m68hc11_opcode));
529 m68hc11_sorted_opcodes = opcodes;
530 num_opcodes = 0;
531 for (i = 0; i < m68hc11_num_opcodes; i++)
532 {
533 if (m68hc11_opcodes[i].arch & current_architecture)
534 {
535 opcodes[num_opcodes] = m68hc11_opcodes[i];
536 if (opcodes[num_opcodes].name[0] == 'b'
537 && opcodes[num_opcodes].format & M6811_OP_JUMP_REL
538 && !(opcodes[num_opcodes].format & M6811_OP_BITMASK))
539 {
540 num_opcodes++;
541 opcodes[num_opcodes] = m68hc11_opcodes[i];
542 }
543 num_opcodes++;
544 for (j = 0; alias_opcodes[j].name != 0; j++)
545 if (strcmp (m68hc11_opcodes[i].name, alias_opcodes[j].name) == 0)
546 {
547 opcodes[num_opcodes] = m68hc11_opcodes[i];
548 opcodes[num_opcodes].name = alias_opcodes[j].alias;
549 num_opcodes++;
550 break;
551 }
552 }
553 }
554 qsort (opcodes, num_opcodes, sizeof (struct m68hc11_opcode), cmp_opcode);
555
556 opc = (struct m68hc11_opcode_def *)
557 xmalloc (num_opcodes * sizeof (struct m68hc11_opcode_def));
558 m68hc11_opcode_defs = opc--;
559
560 /* Insert unique names into hash table. The M6811 instruction set
561 has several identical opcode names that have different opcodes based
562 on the operands. This hash table then provides a quick index to
563 the first opcode with a particular name in the opcode table. */
564 for (i = 0; i < num_opcodes; i++, opcodes++)
565 {
566 int expect;
567
568 if (strcmp (prev_name, opcodes->name))
569 {
570 prev_name = (char *) opcodes->name;
571
572 opc++;
573 opc->format = 0;
574 opc->min_operands = 100;
575 opc->max_operands = 0;
576 opc->nb_modes = 0;
577 opc->opcode = opcodes;
578 opc->used = 0;
579 hash_insert (m68hc11_hash, opcodes->name, (char *) opc);
580 }
581 opc->nb_modes++;
582 opc->format |= opcodes->format;
583
584 /* See how many operands this opcode needs. */
585 expect = 0;
586 if (opcodes->format & M6811_OP_MASK)
587 expect++;
588 if (opcodes->format & M6811_OP_BITMASK)
589 expect++;
590 if (opcodes->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
591 expect++;
592 if (opcodes->format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2))
593 expect++;
594
595 if (expect < opc->min_operands)
596 opc->min_operands = expect;
597 if (expect > opc->max_operands)
598 opc->max_operands = expect;
599 }
600 opc++;
601 m68hc11_nb_opcode_defs = opc - m68hc11_opcode_defs;
602
603 if (flag_print_opcodes)
604 {
605 print_opcode_list ();
606 exit (EXIT_SUCCESS);
607 }
608}
609
610void
611m68hc11_init_after_args ()
612{
613}
60bcf0fa
NC
614\f
615/* Builtin help. */
616
617/* Return a string that represents the operand format for the instruction.
618 When example is true, this generates an example of operand. This is used
619 to give an example and also to generate a test. */
620static char *
621print_opcode_format (opcode, example)
622 struct m68hc11_opcode *opcode;
623 int example;
624{
625 static char buf[128];
626 int format = opcode->format;
627 char *p;
628
629 p = buf;
630 buf[0] = 0;
631 if (format & M6811_OP_IMM8)
632 {
633 if (example)
634 sprintf (p, "#%d", rand () & 0x0FF);
635 else
636 strcpy (p, _("#<imm8>"));
637 p = &p[strlen (p)];
638 }
639
640 if (format & M6811_OP_IMM16)
641 {
642 if (example)
643 sprintf (p, "#%d", rand () & 0x0FFFF);
644 else
645 strcpy (p, _("#<imm16>"));
646 p = &p[strlen (p)];
647 }
648
649 if (format & M6811_OP_IX)
650 {
651 if (example)
652 sprintf (p, "%d,X", rand () & 0x0FF);
653 else
654 strcpy (p, _("<imm8>,X"));
655 p = &p[strlen (p)];
656 }
657
658 if (format & M6811_OP_IY)
659 {
660 if (example)
661 sprintf (p, "%d,X", rand () & 0x0FF);
662 else
663 strcpy (p, _("<imm8>,X"));
664 p = &p[strlen (p)];
665 }
666
667 if (format & M6812_OP_IDX)
668 {
669 if (example)
670 sprintf (p, "%d,X", rand () & 0x0FF);
671 else
672 strcpy (p, "n,r");
673 p = &p[strlen (p)];
674 }
675
676 if (format & M6811_OP_DIRECT)
677 {
678 if (example)
679 sprintf (p, "*Z%d", rand () & 0x0FF);
680 else
681 strcpy (p, _("*<abs8>"));
682 p = &p[strlen (p)];
683 }
684
685 if (format & M6811_OP_BITMASK)
686 {
687 if (buf[0])
688 *p++ = ' ';
689
690 if (example)
691 sprintf (p, "#$%02x", rand () & 0x0FF);
692 else
693 strcpy (p, _("#<mask>"));
694
695 p = &p[strlen (p)];
696 if (format & M6811_OP_JUMP_REL)
697 *p++ = ' ';
698 }
699
700 if (format & M6811_OP_IND16)
701 {
702 if (example)
703 sprintf (p, _("symbol%d"), rand () & 0x0FF);
704 else
705 strcpy (p, _("<abs>"));
706
707 p = &p[strlen (p)];
708 }
709
710 if (format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
711 {
712 if (example)
713 {
714 if (format & M6811_OP_BITMASK)
715 {
716 sprintf (p, ".+%d", rand () & 0x7F);
717 }
718 else
719 {
720 sprintf (p, "L%d", rand () & 0x0FF);
721 }
722 }
723 else
724 strcpy (p, _("<label>"));
725 }
726
727 return buf;
728}
729
730/* Prints the list of instructions with the possible operands. */
731static void
732print_opcode_list ()
733{
734 int i;
735 char *prev_name = "";
736 struct m68hc11_opcode *opcodes;
737 int example = flag_print_opcodes == 2;
738
739 if (example)
fafb6d17
NC
740 printf (_("# Example of `%s' instructions\n\t.sect .text\n_start:\n"),
741 default_cpu);
60bcf0fa
NC
742
743 opcodes = m68hc11_sorted_opcodes;
744
745 /* Walk the list sorted on names (by md_begin). We only report
746 one instruction per line, and we collect the different operand
747 formats. */
748 for (i = 0; i < num_opcodes; i++, opcodes++)
749 {
750 char *fmt = print_opcode_format (opcodes, example);
751
752 if (example)
753 {
754 printf ("L%d:\t", i);
755 printf ("%s %s\n", opcodes->name, fmt);
756 }
757 else
758 {
759 if (strcmp (prev_name, opcodes->name))
760 {
761 if (i > 0)
762 printf ("\n");
763
764 printf ("%-5.5s ", opcodes->name);
765 prev_name = (char *) opcodes->name;
766 }
767 if (fmt[0])
768 printf (" [%s]", fmt);
769 }
770 }
771 printf ("\n");
772}
773
60bcf0fa
NC
774/* Print the instruction format. This operation is called when some
775 instruction is not correct. Instruction format is printed as an
776 error message. */
777static void
778print_insn_format (name)
779 char *name;
780{
781 struct m68hc11_opcode_def *opc;
782 struct m68hc11_opcode *opcode;
783 char buf[128];
784
785 opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash, name);
786 if (opc == NULL)
787 {
788 as_bad (_("Instruction `%s' is not recognized."), name);
789 return;
790 }
791 opcode = opc->opcode;
792
793 as_bad (_("Instruction formats for `%s':"), name);
794 do
795 {
796 char *fmt;
797
798 fmt = print_opcode_format (opcode, 0, 0);
799 sprintf (buf, "\t%-5.5s %s", opcode->name, fmt);
800
801 as_bad ("%s", buf);
802 opcode++;
803 }
804 while (strcmp (opcode->name, name) == 0);
805}
60bcf0fa
NC
806\f
807/* Analysis of 68HC11 and 68HC12 operands. */
808
809/* reg_name_search() finds the register number given its name.
810 Returns the register number or REG_NONE on failure. */
811static register_id
812reg_name_search (name)
813 char *name;
814{
815 if (strcasecmp (name, "x") == 0 || strcasecmp (name, "ix") == 0)
816 return REG_X;
817 if (strcasecmp (name, "y") == 0 || strcasecmp (name, "iy") == 0)
818 return REG_Y;
819 if (strcasecmp (name, "a") == 0)
820 return REG_A;
821 if (strcasecmp (name, "b") == 0)
822 return REG_B;
823 if (strcasecmp (name, "d") == 0)
824 return REG_D;
825 if (strcasecmp (name, "sp") == 0)
826 return REG_SP;
827 if (strcasecmp (name, "pc") == 0)
828 return REG_PC;
829 if (strcasecmp (name, "ccr") == 0)
830 return REG_CCR;
831
832 return REG_NONE;
833}
834
835static char *
836skip_whites (p)
837 char *p;
838{
839 while (*p == ' ' || *p == '\t')
840 p++;
841
842 return p;
843}
844
fafb6d17 845/* Check the string at input_line_pointer
60bcf0fa
NC
846 to see if it is a valid register name. */
847static register_id
848register_name ()
849{
850 register_id reg_number;
851 char c, *p = input_line_pointer;
852
853 if (!is_name_beginner (*p++))
854 return REG_NONE;
855
856 while (is_part_of_name (*p++))
857 continue;
858
859 c = *--p;
860 if (c)
861 *p++ = 0;
862
fafb6d17 863 /* Look to see if it's in the register table. */
60bcf0fa
NC
864 reg_number = reg_name_search (input_line_pointer);
865 if (reg_number != REG_NONE)
866 {
867 if (c)
868 *--p = c;
869
870 input_line_pointer = p;
871 return reg_number;
872 }
873 if (c)
874 *--p = c;
875
876 return reg_number;
877}
878
fafb6d17 879/* Parse a string of operands and return an array of expressions.
60bcf0fa
NC
880
881 Operand mode[0] mode[1] exp[0] exp[1]
882 #n M6811_OP_IMM16 - O_*
883 *<exp> M6811_OP_DIRECT - O_*
884 .{+-}<exp> M6811_OP_JUMP_REL - O_*
885 <exp> M6811_OP_IND16 - O_*
886 ,r N,r M6812_OP_IDX M6812_OP_REG O_constant O_register
887 n,-r M6812_PRE_DEC M6812_OP_REG O_constant O_register
888 n,+r M6812_PRE_INC " "
889 n,r- M6812_POST_DEC " "
890 n,r+ M6812_POST_INC " "
891 A,r B,r D,r M6811_OP_REG M6812_OP_REG O_register O_register
892 [D,r] M6811_OP_IDX_2 M6812_OP_REG O_register O_register
fafb6d17 893 [n,r] M6811_OP_IDX_1 M6812_OP_REG O_constant O_register */
60bcf0fa
NC
894static int
895get_operand (oper, which, opmode)
896 operand *oper;
897 int which;
898 long opmode;
899{
900 char *p = input_line_pointer;
901 int mode;
902 register_id reg;
903
904 oper->exp.X_op = O_absent;
905 oper->reg1 = REG_NONE;
906 oper->reg2 = REG_NONE;
907 mode = M6811_OP_NONE;
908
909 p = skip_whites (p);
910
911 if (*p == 0 || *p == '\n' || *p == '\r')
912 {
913 input_line_pointer = p;
914 return 0;
915 }
916
917 if (*p == '*' && (opmode & (M6811_OP_DIRECT | M6811_OP_IND16)))
918 {
919 mode = M6811_OP_DIRECT;
920 p++;
921 }
922 else if (*p == '#')
923 {
924 if (!(opmode & (M6811_OP_IMM8 | M6811_OP_IMM16 | M6811_OP_BITMASK)))
925 {
926 as_bad (_("Immediate operand is not allowed for operand %d."),
fafb6d17 927 which);
60bcf0fa
NC
928 return -1;
929 }
930
931 mode = M6811_OP_IMM16;
932 p++;
933 if (strncmp (p, "%hi", 3) == 0)
934 {
935 p += 3;
936 mode |= M6811_OP_HIGH_ADDR;
937 }
938 else if (strncmp (p, "%lo", 3) == 0)
939 {
940 p += 3;
941 mode |= M6811_OP_LOW_ADDR;
942 }
943 }
944 else if (*p == '.' && (p[1] == '+' || p[1] == '-'))
945 {
946 p++;
947 mode = M6811_OP_JUMP_REL;
948 }
949 else if (*p == '[')
950 {
951 if (current_architecture & cpu6811)
952 as_bad (_("Indirect indexed addressing is not valid for 68HC11."));
953
954 p++;
955 mode = M6812_OP_IDX_2;
956 p = skip_whites (p);
957 }
958 else if (*p == ',') /* Special handling of ,x and ,y. */
959 {
960 p++;
961 input_line_pointer = p;
962
963 reg = register_name ();
964 if (reg != REG_NONE)
965 {
966 oper->reg1 = reg;
967 oper->exp.X_op = O_constant;
968 oper->exp.X_add_number = 0;
969 oper->mode = M6812_OP_IDX;
970 return 1;
971 }
972 as_bad (_("Spurious `,' or bad indirect register addressing mode."));
973 return -1;
974 }
975 input_line_pointer = p;
976
977 if (mode == M6811_OP_NONE || mode == M6812_OP_IDX_2)
978 reg = register_name ();
979 else
980 reg = REG_NONE;
981
982 if (reg != REG_NONE)
983 {
984 p = skip_whites (input_line_pointer);
985 if (*p == ']' && mode == M6812_OP_IDX_2)
986 {
987 as_bad
988 (_("Missing second register or offset for indexed-indirect mode."));
989 return -1;
990 }
991
992 oper->reg1 = reg;
993 oper->mode = mode | M6812_OP_REG;
994 if (*p != ',')
995 {
996 if (mode == M6812_OP_IDX_2)
997 {
998 as_bad (_("Missing second register for indexed-indirect mode."));
999 return -1;
1000 }
1001 return 1;
1002 }
1003
1004 p++;
1005 input_line_pointer = p;
1006 reg = register_name ();
1007 if (reg != REG_NONE)
1008 {
1009 p = skip_whites (input_line_pointer);
1010 if (mode == M6812_OP_IDX_2)
1011 {
1012 if (*p != ']')
1013 {
1014 as_bad (_("Missing `]' to close indexed-indirect mode."));
1015 return -1;
1016 }
1017 p++;
1018 }
1019 input_line_pointer = p;
1020
1021 oper->reg2 = reg;
1022 return 1;
1023 }
1024 return 1;
1025 }
1026
1027 /* In MRI mode, isolate the operand because we can't distinguish
1028 operands from comments. */
1029 if (flag_mri)
1030 {
1031 char c = 0;
1032
1033 p = skip_whites (p);
1034 while (*p && *p != ' ' && *p != '\t')
1035 p++;
1036
1037 if (*p)
1038 {
1039 c = *p;
1040 *p = 0;
1041 }
1042
1043 /* Parse as an expression. */
1044 expression (&oper->exp);
1045
1046 if (c)
1047 {
1048 *p = c;
1049 }
1050 }
1051 else
1052 {
1053 expression (&oper->exp);
1054 }
1055
1056 if (oper->exp.X_op == O_illegal)
1057 {
1058 as_bad (_("Illegal operand."));
1059 return -1;
1060 }
1061 else if (oper->exp.X_op == O_absent)
1062 {
1063 as_bad (_("Missing operand."));
1064 return -1;
1065 }
1066
1067 p = input_line_pointer;
1068
1069 if (mode == M6811_OP_NONE || mode == M6811_OP_DIRECT
1070 || mode == M6812_OP_IDX_2)
1071 {
1072 p = skip_whites (input_line_pointer);
1073
1074 if (*p == ',')
1075 {
1076 p++;
1077
1078 /* 68HC12 pre increment or decrement. */
1079 if (mode == M6811_OP_NONE)
1080 {
1081 if (*p == '-')
1082 {
1083 mode = M6812_PRE_DEC;
1084 p++;
1085 if (current_architecture & cpu6811)
1086 as_bad (_("Pre-decrement mode is not valid for 68HC11"));
1087 }
1088 else if (*p == '+')
1089 {
1090 mode = M6812_PRE_INC;
1091 p++;
1092 if (current_architecture & cpu6811)
1093 as_bad (_("Pre-increment mode is not valid for 68HC11"));
1094 }
1095 p = skip_whites (p);
1096 }
1097 input_line_pointer = p;
1098 reg = register_name ();
1099
fafb6d17 1100 /* Backtrack. */
60bcf0fa
NC
1101 if (which == 0 && opmode & M6812_OP_IDX_P2
1102 && reg != REG_X && reg != REG_Y
1103 && reg != REG_PC && reg != REG_SP)
1104 {
1105 reg = REG_NONE;
1106 input_line_pointer = p;
1107 }
1108
1109 if (reg == REG_NONE && mode != M6811_OP_DIRECT
1110 && !(mode == M6811_OP_NONE && opmode & M6811_OP_IND16))
1111 {
1112 as_bad (_("Wrong register in register indirect mode."));
1113 return -1;
1114 }
1115 if (mode == M6812_OP_IDX_2)
1116 {
1117 p = skip_whites (input_line_pointer);
1118 if (*p++ != ']')
1119 {
1120 as_bad (_("Missing `]' to close register indirect operand."));
1121 return -1;
1122 }
1123 input_line_pointer = p;
1124 }
1125 if (reg != REG_NONE)
1126 {
1127 oper->reg1 = reg;
1128 if (mode == M6811_OP_NONE)
1129 {
1130 p = input_line_pointer;
1131 if (*p == '-')
1132 {
1133 mode = M6812_POST_DEC;
1134 p++;
1135 if (current_architecture & cpu6811)
1136 as_bad
1137 (_("Post-decrement mode is not valid for 68HC11."));
1138 }
1139 else if (*p == '+')
1140 {
1141 mode = M6812_POST_INC;
1142 p++;
1143 if (current_architecture & cpu6811)
1144 as_bad
1145 (_("Post-increment mode is not valid for 68HC11."));
1146 }
1147 else
1148 mode = M6812_OP_IDX;
1149
1150 input_line_pointer = p;
1151 }
1152 else
1153 mode |= M6812_OP_IDX;
1154
1155 oper->mode = mode;
1156 return 1;
1157 }
1158 }
1159
1160 if (mode == M6812_OP_D_IDX_2)
1161 {
1162 as_bad (_("Invalid indexed indirect mode."));
1163 return -1;
1164 }
1165 }
1166
1167 /* If the mode is not known until now, this is either a label
1168 or an indirect address. */
1169 if (mode == M6811_OP_NONE)
fafb6d17 1170 mode = M6811_OP_IND16 | M6811_OP_JUMP_REL;
60bcf0fa
NC
1171
1172 p = input_line_pointer;
1173 while (*p == ' ' || *p == '\t')
1174 p++;
1175 input_line_pointer = p;
1176 oper->mode = mode;
1177
1178 return 1;
1179}
1180
1181#define M6812_AUTO_INC_DEC (M6812_PRE_INC | M6812_PRE_DEC \
1182 | M6812_POST_INC | M6812_POST_DEC)
1183
1184/* Checks that the number 'num' fits for a given mode. */
1185static int
1186check_range (num, mode)
1187 long num;
1188 int mode;
1189{
1190 /* Auto increment and decrement are ok for [-8..8] without 0. */
1191 if (mode & M6812_AUTO_INC_DEC)
fafb6d17 1192 return (num != 0 && num <= 8 && num >= -8);
60bcf0fa
NC
1193
1194 /* The 68HC12 supports 5, 9 and 16-bits offsets. */
1195 if (mode & (M6812_INDEXED_IND | M6812_INDEXED | M6812_OP_IDX))
fafb6d17 1196 mode = M6811_OP_IND16;
60bcf0fa
NC
1197
1198 if (mode & M6812_OP_JUMP_REL16)
1199 mode = M6811_OP_IND16;
1200
1201 switch (mode)
1202 {
1203 case M6811_OP_IX:
1204 case M6811_OP_IY:
1205 case M6811_OP_DIRECT:
1206 return (num >= 0 && num <= 255) ? 1 : 0;
1207
1208 case M6811_OP_BITMASK:
1209 case M6811_OP_IMM8:
1210 return (((num & 0xFFFFFF00) == 0) || ((num & 0xFFFFFF00) == 0xFFFFFF00))
1211 ? 1 : 0;
1212
1213 case M6811_OP_JUMP_REL:
1214 return (num >= -128 && num <= 127) ? 1 : 0;
1215
1216 case M6811_OP_IND16:
1217 case M6811_OP_IMM16:
1218 return (((num & 0xFFFF0000) == 0) || ((num & 0xFFFF0000) == 0xFFFF0000))
1219 ? 1 : 0;
1220
1221 case M6812_OP_IBCC_MARKER:
1222 case M6812_OP_TBCC_MARKER:
1223 case M6812_OP_DBCC_MARKER:
1224 return (num >= -256 && num <= 255) ? 1 : 0;
1225
1226 case M6812_OP_TRAP_ID:
1227 return ((num >= 0x30 && num <= 0x39)
1228 || (num >= 0x40 && num <= 0x0ff)) ? 1 : 0;
1229
1230 default:
1231 return 0;
1232 }
1233}
60bcf0fa
NC
1234\f
1235/* Gas fixup generation. */
1236
1237/* Put a 1 byte expression described by 'oper'. If this expression contains
1238 unresolved symbols, generate an 8-bit fixup. */
1239static void
1240fixup8 (oper, mode, opmode)
1241 expressionS *oper;
1242 int mode;
1243 int opmode;
1244{
1245 char *f;
1246
1247 f = frag_more (1);
1248
1249 if (oper->X_op == O_constant)
1250 {
1251 if (mode & M6812_OP_TRAP_ID
1252 && !check_range (oper->X_add_number, M6812_OP_TRAP_ID))
1253 {
1254 static char trap_id_warn_once = 0;
1255
1256 as_bad (_("Trap id `%ld' is out of range."), oper->X_add_number);
1257 if (trap_id_warn_once == 0)
1258 {
1259 trap_id_warn_once = 1;
1260 as_bad (_("Trap id must be within [0x30..0x39] or [0x40..0xff]."));
1261 }
1262 }
1263
1264 if (!(mode & M6812_OP_TRAP_ID)
1265 && !check_range (oper->X_add_number, mode))
1266 {
1267 as_bad (_("Operand out of 8-bit range: `%ld'."), oper->X_add_number);
1268 }
1269 number_to_chars_bigendian (f, oper->X_add_number & 0x0FF, 1);
1270 }
1271 else if (oper->X_op != O_register)
1272 {
1273 if (mode & M6812_OP_TRAP_ID)
1274 as_bad (_("The trap id must be a constant."));
1275
1276 if (mode == M6811_OP_JUMP_REL)
1277 {
1278 fixS *fixp;
1279
1280 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
1281 oper, true, BFD_RELOC_8_PCREL);
1282 fixp->fx_pcrel_adjust = 1;
1283 }
1284 else
1285 {
1286 /* Now create an 8-bit fixup. If there was some %hi or %lo
1287 modifier, generate the reloc accordingly. */
1288 fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
1289 oper, false,
1290 ((opmode & M6811_OP_HIGH_ADDR)
1291 ? BFD_RELOC_M68HC11_HI8
1292 : ((opmode & M6811_OP_LOW_ADDR)
1293 ? BFD_RELOC_M68HC11_LO8 : BFD_RELOC_8)));
1294 }
1295 number_to_chars_bigendian (f, 0, 1);
1296 }
1297 else
1298 {
1299 as_fatal (_("Operand `%x' not recognized in fixup8."), oper->X_op);
1300 }
1301}
1302
1303/* Put a 2 bytes expression described by 'oper'. If this expression contains
1304 unresolved symbols, generate a 16-bit fixup. */
1305static void
1306fixup16 (oper, mode, opmode)
1307 expressionS *oper;
1308 int mode;
1309 int opmode ATTRIBUTE_UNUSED;
1310{
1311 char *f;
1312
1313 f = frag_more (2);
1314
1315 if (oper->X_op == O_constant)
1316 {
1317 if (!check_range (oper->X_add_number, mode))
1318 {
1319 as_bad (_("Operand out of 16-bit range: `%ld'."),
fafb6d17 1320 oper->X_add_number);
60bcf0fa
NC
1321 }
1322 number_to_chars_bigendian (f, oper->X_add_number & 0x0FFFF, 2);
1323 }
1324 else if (oper->X_op != O_register)
1325 {
1326 fixS *fixp;
1327
1328 /* Now create a 16-bit fixup. */
1329 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 2,
1330 oper,
1331 (mode & M6812_OP_JUMP_REL16 ? true : false),
1332 (mode & M6812_OP_JUMP_REL16
1333 ? BFD_RELOC_16_PCREL : BFD_RELOC_16));
1334 number_to_chars_bigendian (f, 0, 2);
1335 if (mode & M6812_OP_JUMP_REL16)
1336 fixp->fx_pcrel_adjust = 2;
1337 }
1338 else
1339 {
1340 as_fatal (_("Operand `%x' not recognized in fixup16."), oper->X_op);
1341 }
1342}
60bcf0fa
NC
1343\f
1344/* 68HC11 and 68HC12 code generation. */
1345
1346/* Translate the short branch/bsr instruction into a long branch. */
1347static unsigned char
1348convert_branch (code)
1349 unsigned char code;
1350{
1351 if (IS_OPCODE (code, M6812_BSR))
1352 return M6812_JSR;
1353 else if (IS_OPCODE (code, M6811_BSR))
1354 return M6811_JSR;
1355 else if (IS_OPCODE (code, M6811_BRA))
1356 return (current_architecture & cpu6812) ? M6812_JMP : M6811_JMP;
1357 else
1358 as_fatal (_("Unexpected branch conversion with `%x'"), code);
1359
1360 /* Keep gcc happy. */
1361 return M6811_JSR;
1362}
1363
1364/* Start a new insn that contains at least 'size' bytes. Record the
1365 line information of that insn in the dwarf2 debug sections. */
fafb6d17 1366static char *
60bcf0fa
NC
1367m68hc11_new_insn (size)
1368 int size;
1369{
fafb6d17 1370 char *f;
60bcf0fa
NC
1371
1372 f = frag_more (size);
1373
1374 /* Emit line number information in dwarf2 debug sections. */
1375 if (debug_type == DEBUG_DWARF2)
85a39694 1376 dwarf2_generate_asm_lineno (size);
fafb6d17 1377
60bcf0fa
NC
1378 return f;
1379}
1380
1381/* Builds a jump instruction (bra, bcc, bsr). */
1382static void
1383build_jump_insn (opcode, operands, nb_operands, jmp_mode)
1384 struct m68hc11_opcode *opcode;
1385 operand operands[];
1386 int nb_operands;
1387 int jmp_mode;
1388{
1389 unsigned char code;
1390 int insn_size;
1391 char *f;
1392 unsigned long n;
1393
1394 /* The relative branch convertion is not supported for
1395 brclr and brset. */
1396 assert ((opcode->format & M6811_OP_BITMASK) == 0);
1397 assert (nb_operands == 1);
1398 assert (operands[0].reg1 == REG_NONE && operands[0].reg2 == REG_NONE);
1399
1400 code = opcode->opcode;
1401 insn_size = 1;
1402
1403 n = operands[0].exp.X_add_number;
1404
1405 /* Turn into a long branch:
1406 - when force long branch option (and not for jbcc pseudos),
1407 - when jbcc and the constant is out of -128..127 range,
1408 - when branch optimization is allowed and branch out of range. */
1409 if ((jmp_mode == 0 && flag_force_long_jumps)
1410 || (operands[0].exp.X_op == O_constant
1411 && (!check_range (n, opcode->format) &&
1412 (jmp_mode == 1 || flag_fixed_branchs == 0))))
1413 {
1414 if (code == M6811_BSR || code == M6811_BRA || code == M6812_BSR)
1415 {
1416 code = convert_branch (code);
1417
1418 f = m68hc11_new_insn (1);
1419 number_to_chars_bigendian (f, code, 1);
1420 }
1421 else if (current_architecture & cpu6812)
1422 {
1423 /* 68HC12: translate the bcc into a lbcc. */
1424 f = m68hc11_new_insn (2);
1425 number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1);
1426 number_to_chars_bigendian (f + 1, code, 1);
1427 fixup16 (&operands[0].exp, M6812_OP_JUMP_REL16,
1428 M6812_OP_JUMP_REL16);
1429 return;
1430 }
1431 else
1432 {
1433 /* 68HC11: translate the bcc into b!cc +3; jmp <L>. */
1434 f = m68hc11_new_insn (3);
1435 code ^= 1;
1436 number_to_chars_bigendian (f, code, 1);
1437 number_to_chars_bigendian (f + 1, 3, 1);
1438 number_to_chars_bigendian (f + 2, M6811_JMP, 1);
1439 }
1440 fixup16 (&operands[0].exp, M6811_OP_IND16, M6811_OP_IND16);
1441 return;
1442 }
1443
1444 /* Branch with a constant that must fit in 8-bits. */
1445 if (operands[0].exp.X_op == O_constant)
1446 {
1447 if (!check_range (n, opcode->format))
1448 {
1449 as_bad (_("Operand out of range for a relative branch: `%ld'"),
1450 n);
1451 }
1452 else if (opcode->format & M6812_OP_JUMP_REL16)
1453 {
1454 f = m68hc11_new_insn (4);
1455 number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1);
1456 number_to_chars_bigendian (f + 1, code, 1);
1457 number_to_chars_bigendian (f + 2, n & 0x0ffff, 2);
1458 }
1459 else
1460 {
1461 f = m68hc11_new_insn (2);
1462 number_to_chars_bigendian (f, code, 1);
1463 number_to_chars_bigendian (f + 1, n & 0x0FF, 1);
1464 }
1465 }
1466 else if (opcode->format & M6812_OP_JUMP_REL16)
1467 {
1468 f = m68hc11_new_insn (2);
1469 number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1);
1470 number_to_chars_bigendian (f + 1, code, 1);
1471 fixup16 (&operands[0].exp, M6812_OP_JUMP_REL16, M6812_OP_JUMP_REL16);
1472 }
1473 else
1474 {
1475 char *opcode;
1476
1477 /* Branch offset must fit in 8-bits, don't do some relax. */
1478 if (jmp_mode == 0 && flag_fixed_branchs)
1479 {
1480 opcode = m68hc11_new_insn (1);
1481 number_to_chars_bigendian (opcode, code, 1);
1482 fixup8 (&operands[0].exp, M6811_OP_JUMP_REL, M6811_OP_JUMP_REL);
1483 }
1484
1485 /* bra/bsr made be changed into jmp/jsr. */
1486 else if (code == M6811_BSR || code == M6811_BRA || code == M6812_BSR)
1487 {
1488 opcode = m68hc11_new_insn (2);
1489 number_to_chars_bigendian (opcode, code, 1);
1490 number_to_chars_bigendian (opcode + 1, 0, 1);
df86943d 1491 frag_var (rs_machine_dependent, 2, 1,
60bcf0fa
NC
1492 ENCODE_RELAX (STATE_PC_RELATIVE, STATE_UNDF),
1493 operands[0].exp.X_add_symbol, (offsetT) n, opcode);
1494 }
1495 else if (current_architecture & cpu6812)
1496 {
1497 opcode = m68hc11_new_insn (2);
1498 number_to_chars_bigendian (opcode, code, 1);
1499 number_to_chars_bigendian (opcode + 1, 0, 1);
1500 frag_var (rs_machine_dependent, 2, 2,
1501 ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_UNDF),
1502 operands[0].exp.X_add_symbol, (offsetT) n, opcode);
1503 }
1504 else
1505 {
1506 opcode = m68hc11_new_insn (2);
1507 number_to_chars_bigendian (opcode, code, 1);
1508 number_to_chars_bigendian (opcode + 1, 0, 1);
1509 frag_var (rs_machine_dependent, 3, 3,
1510 ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_UNDF),
1511 operands[0].exp.X_add_symbol, (offsetT) n, opcode);
1512 }
1513 }
1514}
1515
1516/* Builds a dbne/dbeq/tbne/tbeq instruction. */
1517static void
1518build_dbranch_insn (opcode, operands, nb_operands, jmp_mode)
1519 struct m68hc11_opcode *opcode;
1520 operand operands[];
1521 int nb_operands;
1522 int jmp_mode;
1523{
1524 unsigned char code;
1525 int insn_size;
1526 char *f;
1527 unsigned long n;
1528
1529 /* The relative branch convertion is not supported for
1530 brclr and brset. */
1531 assert ((opcode->format & M6811_OP_BITMASK) == 0);
1532 assert (nb_operands == 2);
1533 assert (operands[0].reg1 != REG_NONE);
1534
1535 code = opcode->opcode & 0x0FF;
1536 insn_size = 1;
1537
1538 f = m68hc11_new_insn (1);
1539 number_to_chars_bigendian (f, code, 1);
1540
1541 n = operands[1].exp.X_add_number;
1542 code = operands[0].reg1;
1543
1544 if (operands[0].reg1 == REG_NONE || operands[0].reg1 == REG_CCR
1545 || operands[0].reg1 == REG_PC)
1546 as_bad (_("Invalid register for dbcc/tbcc instruction."));
1547
1548 if (opcode->format & M6812_OP_IBCC_MARKER)
1549 code |= 0x80;
1550 else if (opcode->format & M6812_OP_TBCC_MARKER)
1551 code |= 0x40;
1552
1553 if (!(opcode->format & M6812_OP_EQ_MARKER))
1554 code |= 0x20;
1555
1556 /* Turn into a long branch:
1557 - when force long branch option (and not for jbcc pseudos),
1558 - when jdbcc and the constant is out of -256..255 range,
1559 - when branch optimization is allowed and branch out of range. */
1560 if ((jmp_mode == 0 && flag_force_long_jumps)
1561 || (operands[1].exp.X_op == O_constant
1562 && (!check_range (n, M6812_OP_IBCC_MARKER) &&
1563 (jmp_mode == 1 || flag_fixed_branchs == 0))))
1564 {
1565 f = frag_more (2);
1566 code ^= 0x20;
1567 number_to_chars_bigendian (f, code, 1);
1568 number_to_chars_bigendian (f + 1, M6812_JMP, 1);
1569 fixup16 (&operands[0].exp, M6811_OP_IND16, M6811_OP_IND16);
1570 return;
1571 }
1572
1573 /* Branch with a constant that must fit in 9-bits. */
1574 if (operands[1].exp.X_op == O_constant)
1575 {
1576 if (!check_range (n, M6812_OP_IBCC_MARKER))
1577 {
1578 as_bad (_("Operand out of range for a relative branch: `%ld'"),
1579 n);
1580 }
1581 else
1582 {
1583 if ((long) n < 0)
1584 code |= 0x10;
1585
1586 f = frag_more (2);
1587 number_to_chars_bigendian (f, code, 1);
1588 number_to_chars_bigendian (f + 1, n & 0x0FF, 1);
1589 }
1590 }
1591 else
1592 {
1593 /* Branch offset must fit in 8-bits, don't do some relax. */
1594 if (jmp_mode == 0 && flag_fixed_branchs)
1595 {
1596 fixup8 (&operands[0].exp, M6811_OP_JUMP_REL, M6811_OP_JUMP_REL);
1597 }
1598
1599 else
1600 {
1601 f = frag_more (2);
1602 number_to_chars_bigendian (f, code, 1);
1603 number_to_chars_bigendian (f + 1, 0, 1);
1604 frag_var (rs_machine_dependent, 3, 3,
1605 ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_UNDF),
1606 operands[1].exp.X_add_symbol, (offsetT) n, f);
1607 }
1608 }
1609}
1610
1611#define OP_EXTENDED (M6811_OP_PAGE2 | M6811_OP_PAGE3 | M6811_OP_PAGE4)
1612
1613/* Assemble the post index byte for 68HC12 extended addressing modes. */
1614static int
1615build_indexed_byte (op, format, move_insn)
1616 operand *op;
1617 int format ATTRIBUTE_UNUSED;
1618 int move_insn;
1619{
1620 unsigned char byte = 0;
1621 char *f;
1622 int mode;
1623 long val;
1624
1625 val = op->exp.X_add_number;
1626 mode = op->mode;
1627 if (mode & M6812_AUTO_INC_DEC)
1628 {
1629 byte = 0x20;
1630 if (mode & (M6812_POST_INC | M6812_POST_DEC))
1631 byte |= 0x10;
1632
1633 if (op->exp.X_op == O_constant)
1634 {
1635 if (!check_range (val, mode))
1636 {
1637 as_bad (_("Increment/decrement value is out of range: `%ld'."),
fafb6d17 1638 val);
60bcf0fa
NC
1639 }
1640 if (mode & (M6812_POST_INC | M6812_PRE_INC))
1641 byte |= (val - 1) & 0x07;
1642 else
1643 byte |= (8 - ((val) & 7)) | 0x8;
1644 }
1645 switch (op->reg1)
1646 {
1647 case REG_NONE:
1648 as_fatal (_("Expecting a register."));
1649
1650 case REG_X:
1651 byte |= 0;
1652 break;
1653
1654 case REG_Y:
1655 byte |= 0x40;
1656 break;
1657
1658 case REG_SP:
1659 byte |= 0x80;
1660 break;
1661
1662 default:
1663 as_bad (_("Invalid register for post/pre increment."));
1664 break;
1665 }
1666
1667 f = frag_more (1);
1668 number_to_chars_bigendian (f, byte, 1);
1669 return 1;
1670 }
1671
1672 if (mode & M6812_OP_IDX)
1673 {
1674 switch (op->reg1)
1675 {
1676 case REG_X:
1677 byte = 0;
1678 break;
1679
1680 case REG_Y:
1681 byte = 1;
1682 break;
1683
1684 case REG_SP:
1685 byte = 2;
1686 break;
1687
1688 case REG_PC:
1689 byte = 3;
1690 break;
1691
1692 default:
1693 as_bad (_("Invalid register."));
1694 break;
1695 }
1696 if (op->exp.X_op == O_constant)
1697 {
1698 if (!check_range (val, M6812_OP_IDX))
1699 {
1700 as_bad (_("Offset out of 16-bit range: %ld."), val);
1701 }
1702
1703 if (move_insn && !(val >= -16 && val <= 15))
1704 {
1705 as_bad (_("Offset out of 5-bit range for movw/movb insn."));
1706 return -1;
1707 }
1708
1709 if (val >= -16 && val <= 15 && !(mode & M6812_OP_IDX_2))
1710 {
1711 byte = byte << 6;
1712 byte |= val & 0x1f;
1713 f = frag_more (1);
1714 number_to_chars_bigendian (f, byte, 1);
1715 return 1;
1716 }
1717 else if (val >= -256 && val <= 255 && !(mode & M6812_OP_IDX_2))
1718 {
1719 byte = byte << 3;
1720 byte |= 0xe0;
1721 if (val < 0)
1722 byte |= 0x1;
1723 f = frag_more (2);
1724 number_to_chars_bigendian (f, byte, 1);
1725 number_to_chars_bigendian (f + 1, val & 0x0FF, 1);
1726 return 2;
1727 }
1728 else
1729 {
1730 byte = byte << 3;
1731 if (mode & M6812_OP_IDX_2)
1732 byte |= 0xe3;
1733 else
1734 byte |= 0xe2;
1735
1736 f = frag_more (3);
1737 number_to_chars_bigendian (f, byte, 1);
1738 number_to_chars_bigendian (f + 1, val & 0x0FFFF, 2);
1739 return 3;
1740 }
1741 }
1742 f = frag_more (1);
1743 number_to_chars_bigendian (f, byte, 1);
fafb6d17
NC
1744#if 0
1745 fix_new_exp (frag_now, f - frag_now->fr_literal, 2,
1746 &op->exp, false, BFD_RELOC_16);
1747#endif
60bcf0fa
NC
1748 frag_var (rs_machine_dependent, 2, 2,
1749 ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_UNDF),
1750 op->exp.X_add_symbol, val, f);
1751 return 3;
1752 }
1753
1754 if (mode & M6812_OP_REG)
1755 {
1756 if (mode & M6812_OP_IDX_2)
1757 {
1758 if (op->reg1 != REG_D)
1759 as_bad (_("Expecting register D for indexed indirect mode."));
1760 if (move_insn)
1761 as_bad (_("Indexed indirect mode is not allowed for movb/movw."));
1762
1763 byte = 0xE7;
1764 }
1765 else
1766 {
1767 switch (op->reg1)
1768 {
1769 case REG_A:
1770 byte = 0xE4;
1771 break;
1772
1773 case REG_B:
1774 byte = 0xE5;
1775 break;
1776
1777 default:
1778 as_bad (_("Invalid accumulator register."));
1779
1780 case REG_D:
1781 byte = 0xE6;
1782 break;
1783 }
1784 }
1785 switch (op->reg2)
1786 {
1787 case REG_X:
1788 break;
1789
1790 case REG_Y:
1791 byte |= (1 << 3);
1792 break;
1793
1794 case REG_SP:
1795 byte |= (2 << 3);
1796 break;
1797
1798 case REG_PC:
1799 byte |= (3 << 3);
1800 break;
1801
1802 default:
1803 as_bad (_("Invalid indexed register."));
1804 break;
1805 }
1806 f = frag_more (1);
1807 number_to_chars_bigendian (f, byte, 1);
1808 return 1;
1809 }
1810
1811 as_fatal (_("Addressing mode not implemented yet."));
1812 return 0;
1813}
1814
1815/* Assemble the 68HC12 register mode byte. */
1816static int
1817build_reg_mode (op, format)
1818 operand *op;
1819 int format;
1820{
1821 unsigned char byte;
1822 char *f;
1823
1824 if (format & M6812_OP_SEX_MARKER
1825 && op->reg1 != REG_A && op->reg1 != REG_B && op->reg1 != REG_CCR)
1826 as_bad (_("Invalid source register for this instruction, use 'tfr'."));
1827 else if (op->reg1 == REG_NONE || op->reg1 == REG_PC)
1828 as_bad (_("Invalid source register."));
1829
1830 if (format & M6812_OP_SEX_MARKER
1831 && op->reg2 != REG_D
1832 && op->reg2 != REG_X && op->reg2 != REG_Y && op->reg2 != REG_SP)
1833 as_bad (_("Invalid destination register for this instruction, use 'tfr'."));
1834 else if (op->reg2 == REG_NONE || op->reg2 == REG_PC)
1835 as_bad (_("Invalid destination register."));
1836
1837 byte = (op->reg1 << 4) | (op->reg2);
1838 if (format & M6812_OP_EXG_MARKER)
1839 byte |= 0x80;
1840
1841 f = frag_more (1);
1842 number_to_chars_bigendian (f, byte, 1);
1843 return 1;
1844}
1845
1846/* build_insn takes a pointer to the opcode entry in the opcode table,
1847 the array of operand expressions and builds the correspding instruction.
1848 This operation only deals with non relative jumps insn (need special
1849 handling). */
1850static void
1851build_insn (opcode, operands, nb_operands)
1852 struct m68hc11_opcode *opcode;
1853 operand operands[];
1854 int nb_operands ATTRIBUTE_UNUSED;
1855{
1856 int i;
1857 char *f;
1858 int insn_size = 1;
1859 long format;
1860 int move_insn = 0;
1861
1862 /* Put the page code instruction if there is one. */
1863 format = opcode->format;
1864 if (format & OP_EXTENDED)
1865 {
1866 int page_code;
1867
1868 f = m68hc11_new_insn (2);
1869 if (format & M6811_OP_PAGE2)
1870 page_code = M6811_OPCODE_PAGE2;
1871 else if (format & M6811_OP_PAGE3)
1872 page_code = M6811_OPCODE_PAGE3;
1873 else
1874 page_code = M6811_OPCODE_PAGE4;
1875
1876 number_to_chars_bigendian (f, page_code, 1);
1877 f++;
1878 insn_size = 2;
1879 }
1880 else
1881 f = m68hc11_new_insn (1);
1882
1883 number_to_chars_bigendian (f, opcode->opcode, 1);
1884
1885 i = 0;
1886
1887 /* The 68HC12 movb and movw instructions are special. We have to handle
1888 them in a special way. */
1889 if (format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2))
1890 {
1891 move_insn = 1;
1892 if (format & M6812_OP_IDX)
1893 {
1894 insn_size += build_indexed_byte (&operands[0], format, 1);
1895 i = 1;
1896 format &= ~M6812_OP_IDX;
1897 }
1898 if (format & M6812_OP_IDX_P2)
1899 {
1900 insn_size += build_indexed_byte (&operands[1], format, 1);
1901 i = 0;
1902 format &= ~M6812_OP_IDX_P2;
1903 }
1904 }
1905
1906 if (format & (M6811_OP_DIRECT | M6811_OP_IMM8))
1907 {
1908 insn_size++;
1909 fixup8 (&operands[i].exp,
1910 format & (M6811_OP_DIRECT | M6811_OP_IMM8 | M6812_OP_TRAP_ID),
1911 operands[i].mode);
1912 i++;
1913 }
1914 else if (format & (M6811_OP_IMM16 | M6811_OP_IND16))
1915 {
1916 insn_size += 2;
1917 fixup16 (&operands[i].exp, format & (M6811_OP_IMM16 | M6811_OP_IND16),
1918 operands[i].mode);
1919 i++;
1920 }
1921 else if (format & (M6811_OP_IX | M6811_OP_IY))
1922 {
1923 if ((format & M6811_OP_IX) && (operands[0].reg1 != REG_X))
1924 as_bad (_("Invalid indexed register, expecting register X."));
1925 if ((format & M6811_OP_IY) && (operands[0].reg1 != REG_Y))
1926 as_bad (_("Invalid indexed register, expecting register Y."));
1927
1928 insn_size++;
1929 fixup8 (&operands[0].exp, M6811_OP_IX, operands[0].mode);
1930 i = 1;
1931 }
1932 else if (format &
1933 (M6812_OP_IDX | M6812_OP_IDX_2 | M6812_OP_IDX_1 | M6812_OP_D_IDX))
1934 {
1935 insn_size += build_indexed_byte (&operands[i], format, move_insn);
1936 i++;
1937 }
1938 else if (format & M6812_OP_REG && current_architecture & cpu6812)
1939 {
1940 insn_size += build_reg_mode (&operands[i], format);
1941 i++;
1942 }
1943 if (format & M6811_OP_BITMASK)
1944 {
1945 insn_size++;
1946 fixup8 (&operands[i].exp, M6811_OP_BITMASK, operands[i].mode);
1947 i++;
1948 }
1949 if (format & M6811_OP_JUMP_REL)
1950 {
1951 insn_size++;
1952 fixup8 (&operands[i].exp, M6811_OP_JUMP_REL, operands[i].mode);
1953 i++;
1954 }
1955 else if (format & M6812_OP_IND16_P2)
1956 {
1957 insn_size += 2;
1958 fixup16 (&operands[1].exp, M6811_OP_IND16, operands[1].mode);
1959 }
1960}
60bcf0fa
NC
1961\f
1962/* Opcode identification and operand analysis. */
1963
1964/* find() gets a pointer to an entry in the opcode table. It must look at all
1965 opcodes with the same name and use the operands to choose the correct
1966 opcode. Returns the opcode pointer if there was a match and 0 if none. */
1967static struct m68hc11_opcode *
1968find (opc, operands, nb_operands)
1969 struct m68hc11_opcode_def *opc;
1970 operand operands[];
1971 int nb_operands;
1972{
1973 int i, match, pos;
1974 struct m68hc11_opcode *opcode;
1975 struct m68hc11_opcode *op_indirect;
1976
1977 op_indirect = 0;
1978 opcode = opc->opcode;
1979
1980 /* Now search the opcode table table for one with operands
1981 that matches what we've got. We're only done if the operands matched so
1982 far AND there are no more to check. */
1983 for (pos = match = 0; match == 0 && pos < opc->nb_modes; pos++, opcode++)
1984 {
1985 int poss_indirect = 0;
1986 long format = opcode->format;
1987 int expect;
1988
1989 expect = 0;
1990 if (opcode->format & M6811_OP_MASK)
1991 expect++;
1992 if (opcode->format & M6811_OP_BITMASK)
1993 expect++;
1994 if (opcode->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
1995 expect++;
1996 if (opcode->format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2))
1997 expect++;
1998
1999 for (i = 0; expect == nb_operands && i < nb_operands; i++)
2000 {
2001 int mode = operands[i].mode;
2002
2003 if (mode & M6811_OP_IMM16)
2004 {
2005 if (format &
2006 (M6811_OP_IMM8 | M6811_OP_IMM16 | M6811_OP_BITMASK))
2007 continue;
2008 break;
2009 }
2010 if (mode == M6811_OP_DIRECT)
2011 {
2012 if (format & M6811_OP_DIRECT)
2013 continue;
2014
2015 /* If the operand is a page 0 operand, remember a
2016 possible <abs-16> addressing mode. We mark
2017 this and continue to check other operands. */
2018 if (format & M6811_OP_IND16
2019 && flag_strict_direct_addressing && op_indirect == 0)
2020 {
2021 poss_indirect = 1;
2022 continue;
2023 }
2024 break;
2025 }
2026 if (mode & M6811_OP_IND16)
2027 {
2028 if (i == 0 && (format & M6811_OP_IND16) != 0)
2029 continue;
2030 if (i != 0 && (format & M6812_OP_IND16_P2) != 0)
2031 continue;
2032 if (i == 0 && (format & M6811_OP_BITMASK))
2033 break;
2034 }
2035 if (mode & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
2036 {
2037 if (format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
2038 continue;
2039 }
2040 if (mode & M6812_OP_REG)
2041 {
df86943d
NC
2042 if (i == 0
2043 && (format & M6812_OP_REG)
2044 && (operands[i].reg2 == REG_NONE))
60bcf0fa 2045 continue;
df86943d
NC
2046 if (i == 0
2047 && (format & M6812_OP_REG)
2048 && (format & M6812_OP_REG_2)
2049 && (operands[i].reg2 != REG_NONE))
60bcf0fa 2050 continue;
df86943d
NC
2051 if (i == 0
2052 && (format & M6812_OP_IDX)
2053 && (operands[i].reg2 != REG_NONE))
2054 continue;
2055 if (i == 0
2056 && (format & M6812_OP_D_IDX))
2057 continue;
2058 if (i == 0
2059 && (format & M6812_OP_IDX)
60bcf0fa
NC
2060 && (format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2)))
2061 continue;
df86943d
NC
2062 if (i == 1
2063 && (format & M6812_OP_IDX_P2))
60bcf0fa
NC
2064 continue;
2065 break;
2066 }
2067 if (mode & M6812_OP_IDX)
2068 {
2069 if (format & M6811_OP_IX && operands[i].reg1 == REG_X)
2070 continue;
2071 if (format & M6811_OP_IY && operands[i].reg1 == REG_Y)
2072 continue;
2073 if (i == 0
2074 && format & (M6812_OP_IDX | M6812_OP_IDX_1 | M6812_OP_IDX_2)
2075 && (operands[i].reg1 == REG_X
2076 || operands[i].reg1 == REG_Y
2077 || operands[i].reg1 == REG_SP
2078 || operands[i].reg1 == REG_PC))
2079 continue;
2080 if (i == 1 && format & M6812_OP_IDX_P2)
2081 continue;
2082 }
2083 if (mode & M6812_AUTO_INC_DEC)
2084 {
2085 if (i == 0
2086 && format & (M6812_OP_IDX | M6812_OP_IDX_1 |
2087 M6812_OP_IDX_2))
2088 continue;
2089 if (i == 1 && format & M6812_OP_IDX_P2)
2090 continue;
2091 }
2092 break;
2093 }
2094 match = i == nb_operands;
2095
2096 /* Operands are ok but an operand uses page 0 addressing mode
2097 while the insn supports abs-16 mode. Keep a reference to this
2098 insns in case there is no insn supporting page 0 addressing. */
2099 if (match && poss_indirect)
2100 {
2101 op_indirect = opcode;
2102 match = 0;
2103 }
2104 if (match)
2105 break;
2106 }
2107
2108 /* Page 0 addressing is used but not supported by any insn.
2109 If absolute addresses are supported, we use that insn. */
2110 if (match == 0 && op_indirect)
2111 {
2112 opcode = op_indirect;
2113 match = 1;
2114 }
2115
2116 if (!match)
2117 {
2118 return (0);
2119 }
2120
2121 return opcode;
2122}
2123
60bcf0fa
NC
2124/* Find the real opcode and its associated operands. We use a progressive
2125 approach here. On entry, 'opc' points to the first opcode in the
2126 table that matches the opcode name in the source line. We try to
2127 isolate an operand, find a possible match in the opcode table.
2128 We isolate another operand if no match were found. The table 'operands'
2129 is filled while operands are recognized.
2130
2131 Returns the opcode pointer that matches the opcode name in the
2132 source line and the associated operands. */
2133static struct m68hc11_opcode *
2134find_opcode (opc, operands, nb_operands)
2135 struct m68hc11_opcode_def *opc;
2136 operand operands[];
2137 int *nb_operands;
2138{
2139 struct m68hc11_opcode *opcode;
2140 int i;
2141
2142 if (opc->max_operands == 0)
2143 {
2144 *nb_operands = 0;
2145 return opc->opcode;
2146 }
2147
2148 for (i = 0; i < opc->max_operands;)
2149 {
2150 int result;
2151
2152 result = get_operand (&operands[i], i, opc->format);
2153 if (result <= 0)
fafb6d17 2154 return 0;
60bcf0fa
NC
2155
2156 /* Special case where the bitmask of the bclr/brclr
2157 instructions is not introduced by #.
2158 Example: bclr 3,x $80. */
2159 if (i == 1 && (opc->format & M6811_OP_BITMASK)
2160 && (operands[i].mode & M6811_OP_IND16))
2161 {
2162 operands[i].mode = M6811_OP_IMM16;
2163 }
2164
2165 i += result;
2166 *nb_operands = i;
2167 if (i >= opc->min_operands)
2168 {
2169 opcode = find (opc, operands, i);
2170 if (opcode)
fafb6d17 2171 return opcode;
60bcf0fa
NC
2172 }
2173
2174 if (*input_line_pointer == ',')
2175 input_line_pointer++;
2176 }
82efde3a 2177
60bcf0fa
NC
2178 return 0;
2179}
2180
2181#define M6812_XBCC_MARKER (M6812_OP_TBCC_MARKER \
2182 | M6812_OP_DBCC_MARKER \
2183 | M6812_OP_IBCC_MARKER)
60bcf0fa
NC
2184\f
2185/* Gas line assembler entry point. */
2186
2187/* This is the main entry point for the machine-dependent assembler. str
2188 points to a machine-dependent instruction. This function is supposed to
2189 emit the frags/bytes it assembles to. */
2190void
2191md_assemble (str)
2192 char *str;
2193{
2194 struct m68hc11_opcode_def *opc;
2195 struct m68hc11_opcode *opcode;
2196
2197 unsigned char *op_start, *save;
2198 unsigned char *op_end;
2199 char name[20];
2200 int nlen = 0;
2201 operand operands[M6811_MAX_OPERANDS];
2202 int nb_operands;
2203 int branch_optimize = 0;
2204 int alias_id = -1;
2205
fafb6d17 2206 /* Drop leading whitespace. */
60bcf0fa
NC
2207 while (*str == ' ')
2208 str++;
2209
2210 /* Find the opcode end and get the opcode in 'name'. The opcode is forced
2211 lower case (the opcode table only has lower case op-codes). */
2212 for (op_start = op_end = (unsigned char *) (str);
2213 *op_end && nlen < 20 && !is_end_of_line[*op_end] && *op_end != ' ';
2214 op_end++)
2215 {
2216 name[nlen] = tolower (op_start[nlen]);
2217 nlen++;
2218 }
2219 name[nlen] = 0;
2220
2221 if (nlen == 0)
2222 {
2223 as_bad (_("No instruction or missing opcode."));
2224 return;
2225 }
2226
2227 /* Find the opcode definition given its name. */
2228 opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash, name);
2229
2230 /* If it's not recognized, look for 'jbsr' and 'jbxx'. These are
2231 pseudo insns for relative branch. For these branchs, we always
2232 optimize them (turned into absolute branchs) even if --short-branchs
2233 is given. */
2234 if (opc == NULL && name[0] == 'j' && name[1] == 'b')
2235 {
2236 opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash, &name[1]);
2237 if (opc
2238 && (!(opc->format & M6811_OP_JUMP_REL)
2239 || (opc->format & M6811_OP_BITMASK)))
2240 opc = 0;
2241 if (opc)
2242 branch_optimize = 1;
2243 }
2244
2245 /* The following test should probably be removed. This is not conform
2246 to Motorola assembler specs. */
2247 if (opc == NULL && flag_mri)
2248 {
2249 if (*op_end == ' ' || *op_end == '\t')
2250 {
2251 while (*op_end == ' ' || *op_end == '\t')
2252 op_end++;
2253
2254 if (nlen < 19
2255 && (*op_end &&
2256 (is_end_of_line[op_end[1]]
2257 || op_end[1] == ' ' || op_end[1] == '\t'
2258 || !isalnum (op_end[1])))
2259 && (*op_end == 'a' || *op_end == 'b'
2260 || *op_end == 'A' || *op_end == 'B'
2261 || *op_end == 'd' || *op_end == 'D'
2262 || *op_end == 'x' || *op_end == 'X'
2263 || *op_end == 'y' || *op_end == 'Y'))
2264 {
2265 name[nlen++] = tolower (*op_end++);
2266 name[nlen] = 0;
2267 opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash,
2268 name);
2269 }
2270 }
2271 }
2272
2273 /* Identify a possible instruction alias. There are some on the
2274 68HC12 to emulate a fiew 68HC11 instructions. */
2275 if (opc == NULL && (current_architecture & cpu6812))
2276 {
2277 int i;
2278
2279 for (i = 0; i < m68hc12_num_alias; i++)
2280 if (strcmp (m68hc12_alias[i].name, name) == 0)
2281 {
2282 alias_id = i;
2283 break;
2284 }
2285 }
2286 if (opc == NULL && alias_id < 0)
2287 {
2288 as_bad (_("Opcode `%s' is not recognized."), name);
2289 return;
2290 }
2291 save = input_line_pointer;
2292 input_line_pointer = op_end;
2293
2294 if (opc)
2295 {
2296 opc->used++;
2297 opcode = find_opcode (opc, operands, &nb_operands);
2298 }
2299 else
2300 opcode = 0;
2301
2302 if ((opcode || alias_id >= 0) && !flag_mri)
2303 {
2304 char *p = input_line_pointer;
2305
2306 while (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r')
2307 p++;
2308
2309 if (*p != '\n' && *p)
2310 as_bad (_("Garbage at end of instruction: `%s'."), p);
2311 }
2312
2313 input_line_pointer = save;
2314
2315 if (alias_id >= 0)
2316 {
2317 char *f = m68hc11_new_insn (m68hc12_alias[alias_id].size);
fafb6d17 2318
60bcf0fa
NC
2319 number_to_chars_bigendian (f, m68hc12_alias[alias_id].code1, 1);
2320 if (m68hc12_alias[alias_id].size > 1)
2321 number_to_chars_bigendian (f + 1, m68hc12_alias[alias_id].code2, 1);
2322
2323 return;
2324 }
2325
2326 /* Opcode is known but does not have valid operands. Print out the
2327 syntax for this opcode. */
2328 if (opcode == 0)
2329 {
2330 if (flag_print_insn_syntax)
2331 print_insn_format (name);
2332
2333 as_bad (_("Invalid operand for `%s'"), name);
2334 return;
2335 }
2336
2337 /* Treat dbeq/ibeq/tbeq instructions in a special way. The branch is
2338 relative and must be in the range -256..255 (9-bits). */
2339 if ((opcode->format & M6812_XBCC_MARKER)
2340 && (opcode->format & M6811_OP_JUMP_REL))
2341 build_dbranch_insn (opcode, operands, nb_operands);
2342
2343 /* Relative jumps instructions are taken care of separately. We have to make
2344 sure that the relative branch is within the range -128..127. If it's out
2345 of range, the instructions are changed into absolute instructions.
2346 This is not supported for the brset and brclr instructions. */
2347 else if ((opcode->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
2348 && !(opcode->format & M6811_OP_BITMASK))
2349 build_jump_insn (opcode, operands, nb_operands, branch_optimize);
2350 else
2351 build_insn (opcode, operands, nb_operands);
2352}
60bcf0fa
NC
2353\f
2354/* Relocation, relaxation and frag conversions. */
60bcf0fa
NC
2355long
2356md_pcrel_from_section (fixp, sec)
2357 fixS *fixp;
2358 segT sec;
2359{
2360 int adjust;
2361 if (fixp->fx_addsy != (symbolS *) NULL
2362 && (!S_IS_DEFINED (fixp->fx_addsy)
fafb6d17 2363 || (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
60bcf0fa
NC
2364 return 0;
2365
2366 adjust = fixp->fx_pcrel_adjust;
2367 return fixp->fx_frag->fr_address + fixp->fx_where + adjust;
2368}
2369
2370/* If while processing a fixup, a reloc really needs to be created
2371 then it is done here. */
2372arelent *
2373tc_gen_reloc (section, fixp)
2374 asection *section;
2375 fixS *fixp;
2376{
2377 arelent *reloc;
2378
2379 reloc = (arelent *) xmalloc (sizeof (arelent));
2380 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
2381 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
2382 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
2383 if (fixp->fx_r_type == 0)
2384 reloc->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_16);
2385 else
2386 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
2387 if (reloc->howto == (reloc_howto_type *) NULL)
2388 {
2389 as_bad_where (fixp->fx_file, fixp->fx_line,
2390 _("Relocation %d is not supported by object file format."),
2391 (int) fixp->fx_r_type);
2392 return NULL;
2393 }
2394
2395 if (!fixp->fx_pcrel)
2396 reloc->addend = fixp->fx_addnumber;
2397 else
2398 reloc->addend = (section->vma
2399 + (fixp->fx_pcrel_adjust == 64
2400 ? -1 : fixp->fx_pcrel_adjust)
2401 + fixp->fx_addnumber
2402 + md_pcrel_from_section (fixp, section));
2403 return reloc;
2404}
2405
2406void
2407md_convert_frag (abfd, sec, fragP)
2408 bfd *abfd ATTRIBUTE_UNUSED;
2409 asection *sec ATTRIBUTE_UNUSED;
2410 fragS *fragP;
2411{
2412 fixS *fixp;
2413 long disp;
2414 char *buffer_address = fragP->fr_literal;
2415
2416 /* Address in object code of the displacement. */
2417 register int object_address = fragP->fr_fix + fragP->fr_address;
2418
2419 buffer_address += fragP->fr_fix;
2420
2421 /* The displacement of the address, from current location. */
2422 disp = fragP->fr_symbol ? S_GET_VALUE (fragP->fr_symbol) : 0;
2423 disp = (disp + fragP->fr_offset) - object_address;
2424 disp += symbol_get_frag (fragP->fr_symbol)->fr_address;
2425
2426 switch (fragP->fr_subtype)
2427 {
2428 case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE):
2429 fragP->fr_opcode[1] = disp;
2430 break;
2431
2432 case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD):
2433 /* This relax is only for bsr and bra. */
2434 assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
2435 || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
2436 || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
2437
2438 fragP->fr_opcode[0] = convert_branch (fragP->fr_opcode[0]);
2439
2440 fix_new (fragP, fragP->fr_fix - 1, 2,
2441 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
2442 fragP->fr_fix += 1;
2443 break;
2444
2445 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_BYTE):
2446 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_BYTE):
2447 fragP->fr_opcode[1] = disp;
2448 break;
2449
2450 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_WORD):
2451 /* Invert branch. */
2452 fragP->fr_opcode[0] ^= 1;
fafb6d17 2453 fragP->fr_opcode[1] = 3; /* Branch offset. */
60bcf0fa
NC
2454 buffer_address[0] = M6811_JMP;
2455 fix_new (fragP, fragP->fr_fix + 1, 2,
2456 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
2457 fragP->fr_fix += 3;
2458 break;
2459
2460 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_WORD):
2461 /* Translate branch into a long branch. */
2462 fragP->fr_opcode[1] = fragP->fr_opcode[0];
2463 fragP->fr_opcode[0] = M6811_OPCODE_PAGE2;
2464
2465 fixp = fix_new (fragP, fragP->fr_fix, 2,
2466 fragP->fr_symbol, fragP->fr_offset, 1,
2467 BFD_RELOC_16_PCREL);
2468 fixp->fx_pcrel_adjust = 2;
2469 fragP->fr_fix += 2;
2470 break;
2471
2472 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS5):
2473 fragP->fr_opcode[0] = fragP->fr_opcode[0] << 5;
2474 fragP->fr_opcode[0] |= disp & 0x1f;
2475 break;
2476
2477 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9):
2478 fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3);
2479 fragP->fr_opcode[0] |= 0xE0;
2480 fix_new (fragP, fragP->fr_fix + 1, 1,
2481 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_8);
2482 fragP->fr_fix += 1;
2483 break;
2484
2485 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16):
2486 fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3);
2487 fragP->fr_opcode[0] |= 0xE2;
2488 fix_new (fragP, fragP->fr_fix, 2,
2489 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
2490 fragP->fr_fix += 1;
2491 break;
2492
2493 case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_BYTE):
2494 if (disp < 0)
2495 fragP->fr_opcode[0] |= 0x10;
2496
2497 fragP->fr_opcode[1] = disp & 0x0FF;
2498 break;
2499
2500 case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_WORD):
2501 /* Invert branch. */
2502 fragP->fr_opcode[0] ^= 0x20;
2503 fragP->fr_opcode[1] = 3; /* Branch offset. */
2504 buffer_address[0] = M6812_JMP;
2505 fix_new (fragP, fragP->fr_fix + 1, 2,
2506 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
2507 fragP->fr_fix += 3;
2508 break;
2509
2510 default:
2511 break;
2512 }
2513}
2514
2515/* Force truly undefined symbols to their maximum size, and generally set up
2516 the frag list to be relaxed. */
2517int
2518md_estimate_size_before_relax (fragP, segment)
2519 fragS *fragP;
2520 asection *segment;
2521{
2522 int old_fr_fix;
2523 char *buffer_address = fragP->fr_fix + fragP->fr_literal;
2524
2525 old_fr_fix = fragP->fr_fix;
2526
2527 switch (fragP->fr_subtype)
2528 {
2529 case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_UNDF):
2530
2531 /* This relax is only for bsr and bra. */
2532 assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
2533 || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
2534 || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
2535
2536 /* A relaxable case. */
2537 if (S_GET_SEGMENT (fragP->fr_symbol) == segment)
2538 {
2539 fragP->fr_subtype = ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE);
2540 }
2541 else
2542 {
2543 if (flag_fixed_branchs)
2544 as_bad_where (fragP->fr_file, fragP->fr_line,
2545 _("bra or bsr with undefined symbol."));
2546
2547 /* The symbol is undefined or in a separate section. Turn bra into a
2548 jmp and bsr into a jsr. The insn becomes 3 bytes long (instead of
2549 2). A fixup is necessary for the unresolved symbol address. */
2550
2551 fragP->fr_opcode[0] = convert_branch (fragP->fr_opcode[0]);
2552
2553 fragP->fr_fix++;
2554 fix_new (fragP, old_fr_fix - 1, 2, fragP->fr_symbol,
2555 fragP->fr_offset, 0, BFD_RELOC_16);
2556 frag_wane (fragP);
2557 }
2558 break;
2559
2560 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_UNDF):
2561 assert (current_architecture & cpu6811);
2562
2563 if (S_GET_SEGMENT (fragP->fr_symbol) == segment)
2564 {
2565 fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH,
2566 STATE_BYTE);
2567 }
2568 else
2569 {
fafb6d17
NC
2570 fragP->fr_opcode[0] ^= 1; /* Reverse sense of branch. */
2571 fragP->fr_opcode[1] = 3; /* Skip next jmp insn (3 bytes). */
60bcf0fa
NC
2572
2573 /* Don't use fr_opcode[2] because this may be
2574 in a different frag. */
2575 buffer_address[0] = M6811_JMP;
2576
2577 fragP->fr_fix++;
2578 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
2579 fragP->fr_offset, 0, BFD_RELOC_16);
2580 fragP->fr_fix += 2;
2581 frag_wane (fragP);
2582 }
2583 break;
2584
2585 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_UNDF):
2586 assert (current_architecture & cpu6812);
2587
2588 if (S_GET_SEGMENT (fragP->fr_symbol) == segment)
2589 {
2590 fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_OFFSET,
2591 STATE_BITS5);
2592 }
2593 else
2594 {
2595 /* Switch the indexed operation to 16-bit mode. */
2596 if ((fragP->fr_opcode[1] & 0x21) == 0x20)
2597 fragP->fr_opcode[1] = (fragP->fr_opcode[1] >> 3) | 0xc0 | 0x02;
2598
2599 fragP->fr_fix++;
2600 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
2601 fragP->fr_offset, 0, BFD_RELOC_16);
2602 fragP->fr_fix += 2;
2603 frag_wane (fragP);
2604 }
2605 break;
2606
2607 case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_UNDF):
2608 assert (current_architecture & cpu6812);
2609
2610 if (S_GET_SEGMENT (fragP->fr_symbol) == segment)
2611 {
2612 fragP->fr_subtype = ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_BYTE);
2613 }
2614 else
2615 {
fafb6d17 2616 fragP->fr_opcode[0] ^= 0x20; /* Reverse sense of branch. */
60bcf0fa
NC
2617 fragP->fr_opcode[1] = 3; /* Skip next jmp insn (3 bytes). */
2618
2619 /* Don't use fr_opcode[2] because this may be
2620 in a different frag. */
2621 buffer_address[0] = M6812_JMP;
2622
2623 fragP->fr_fix++;
2624 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
2625 fragP->fr_offset, 0, BFD_RELOC_16);
2626 fragP->fr_fix += 2;
2627 frag_wane (fragP);
2628 }
2629 break;
2630
2631 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_UNDF):
2632 assert (current_architecture & cpu6812);
2633
2634 if (S_GET_SEGMENT (fragP->fr_symbol) == segment)
2635 {
2636 fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812,
2637 STATE_BYTE);
2638 }
2639 else
2640 {
2641 /* Translate into a lbcc branch. */
2642 fragP->fr_opcode[1] = fragP->fr_opcode[0];
2643 fragP->fr_opcode[0] = M6811_OPCODE_PAGE2;
2644
2645 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
2646 fragP->fr_offset, 0, BFD_RELOC_16_PCREL);
2647 fragP->fr_fix += 2;
2648 frag_wane (fragP);
2649 }
2650 break;
2651
2652 default:
2653 as_fatal (_("Subtype %d is not recognized."), fragP->fr_subtype);
2654 }
2655
2656 return (fragP->fr_fix - old_fr_fix);
2657}
2658
2659int
2660md_apply_fix (fixp, valuep)
2661 fixS *fixp;
2662 valueT *valuep;
2663{
2664 char *where;
2665 long value;
2666 int op_type;
2667
2668 if (fixp->fx_addsy == (symbolS *) NULL)
2669 {
2670 value = *valuep;
2671 fixp->fx_done = 1;
2672 }
2673 else if (fixp->fx_pcrel)
2674 {
2675 value = *valuep;
2676 }
2677 else
2678 {
2679 value = fixp->fx_offset;
2680 if (fixp->fx_subsy != (symbolS *) NULL)
2681 {
2682 if (S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
2683 {
2684 value -= S_GET_VALUE (fixp->fx_subsy);
2685 }
2686 else
2687 {
2688 /* We don't actually support subtracting a symbol. */
2689 as_bad_where (fixp->fx_file, fixp->fx_line,
2690 _("Expression too complex."));
2691 }
2692 }
2693 }
2694
2695 op_type = fixp->fx_r_type;
2696
2697 /* Patch the instruction with the resolved operand. Elf relocation
2698 info will also be generated to take care of linker/loader fixups.
2699 The 68HC11 addresses only 64Kb, we are only concerned by 8 and 16-bit
2700 relocs. BFD_RELOC_8 is basically used for .page0 access (the linker
2701 will warn for overflows). BFD_RELOC_8_PCREL should not be generated
2702 because it's either resolved or turned out into non-relative insns (see
2703 relax table, bcc, bra, bsr transformations)
2704
2705 The BFD_RELOC_32 is necessary for the support of --gstabs. */
2706 where = fixp->fx_frag->fr_literal + fixp->fx_where;
2707
2708 switch (fixp->fx_r_type)
2709 {
2710 case BFD_RELOC_32:
2711 bfd_putb32 ((bfd_vma) value, (unsigned char *) where);
2712 break;
2713
2714 case BFD_RELOC_16:
2715 case BFD_RELOC_16_PCREL:
2716 bfd_putb16 ((bfd_vma) value, (unsigned char *) where);
2717 if (value < -65537 || value > 65535)
2718 as_bad_where (fixp->fx_file, fixp->fx_line,
2719 _("Value out of 16-bit range."));
2720 break;
2721
2722 case BFD_RELOC_M68HC11_HI8:
2723 value = value >> 8;
fafb6d17 2724 /* Fall through. */
60bcf0fa
NC
2725
2726 case BFD_RELOC_M68HC11_LO8:
2727 case BFD_RELOC_8:
fafb6d17
NC
2728#if 0
2729 bfd_putb8 ((bfd_vma) value, (unsigned char *) where);
2730#endif
60bcf0fa
NC
2731 ((bfd_byte *) where)[0] = (bfd_byte) value;
2732 break;
2733
2734 case BFD_RELOC_8_PCREL:
fafb6d17
NC
2735#if 0
2736 bfd_putb8 ((bfd_vma) value, (unsigned char *) where);
2737#endif
60bcf0fa
NC
2738 ((bfd_byte *) where)[0] = (bfd_byte) value;
2739
2740 if (value < -128 || value > 127)
2741 as_bad_where (fixp->fx_file, fixp->fx_line,
2742 _("Value %ld too large for 8-bit PC-relative branch."),
2743 value);
2744 break;
2745
2746 case BFD_RELOC_M68HC11_3B:
2747 if (value <= 0 || value > 8)
2748 as_bad_where (fixp->fx_file, fixp->fx_line,
2749 _("Auto increment/decrement offset '%ld' is out of range."),
2750 value);
2751 if (where[0] & 0x8)
2752 value = 8 - value;
2753 else
2754 value--;
2755
2756 where[0] = where[0] | (value & 0x07);
2757 break;
2758
2759 default:
2760 as_fatal (_("Line %d: unknown relocation type: 0x%x."),
2761 fixp->fx_line, fixp->fx_r_type);
2762 }
82efde3a 2763
60bcf0fa
NC
2764 return 0;
2765}
2766
2767int
2768m68hc11_cleanup ()
2769{
2770 return 1;
2771}
2772
2773void
2774m68hc11_end_of_source ()
2775{
2776 segT saved_seg;
2777 subsegT saved_subseg;
2778 segT debug_info;
fafb6d17 2779 char *p;
60bcf0fa 2780 long total_size = 0;
fafb6d17 2781
60bcf0fa
NC
2782 if (debug_type != DEBUG_DWARF2)
2783 return;
fafb6d17 2784
60bcf0fa
NC
2785 dwarf2_finish ();
2786
2787 saved_seg = now_seg;
2788 saved_subseg = now_subseg;
2789
2790 debug_info = subseg_new (".debug_info", 0);
2791 bfd_set_section_flags (stdoutput, debug_info, SEC_READONLY);
2792 subseg_set (debug_info, 0);
2793 p = frag_more (10);
2794 total_size = 12;
fafb6d17 2795
60bcf0fa
NC
2796# define STUFF(val,size) md_number_to_chars (p, val, size); p += size;
2797 STUFF (total_size, 4); /* Length of compilation unit. */
2798 STUFF (2, 2); /* Dwarf version */
2799 STUFF (0, 4);
2800 STUFF (2, 1); /* Pointer size */
2801 STUFF (1, 1); /* Compile unit */
2802 STUFF (0, 4);
2803
2804 now_subseg = saved_subseg;
2805 now_seg = saved_seg;
2806}