Rotate ChangeLogs
[deliverable/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 {
ae3e85dd
SC
1076 int possible_mode = M6811_OP_NONE;
1077 char *old_input_line;
60bcf0fa
NC
1078 p++;
1079
1080 /* 68HC12 pre increment or decrement. */
1081 if (mode == M6811_OP_NONE)
1082 {
1083 if (*p == '-')
1084 {
ae3e85dd 1085 possible_mode = M6812_PRE_DEC;
60bcf0fa 1086 p++;
60bcf0fa
NC
1087 }
1088 else if (*p == '+')
1089 {
ae3e85dd 1090 possible_mode = M6812_PRE_INC;
60bcf0fa 1091 p++;
60bcf0fa
NC
1092 }
1093 p = skip_whites (p);
1094 }
ae3e85dd 1095 old_input_line = input_line_pointer;
60bcf0fa
NC
1096 input_line_pointer = p;
1097 reg = register_name ();
1098
ae3e85dd
SC
1099 /* Backtrack if we have a valid constant expression and
1100 it does not correspond to the offset of the 68HC12 indexed
1101 addressing mode (as in N,x). */
1102 if (reg == REG_NONE && mode == M6811_OP_NONE
1103 && possible_mode != M6811_OP_NONE)
1104 {
1105 oper->mode = M6811_OP_IND16 | M6811_OP_JUMP_REL;
1106 input_line_pointer = skip_whites (old_input_line);
1107 return 1;
1108 }
1109
1110 if (possible_mode != M6811_OP_NONE)
1111 mode = possible_mode;
bc805888 1112
ae3e85dd
SC
1113 if ((current_architecture & cpu6811)
1114 && possible_mode != M6811_OP_NONE)
bc805888 1115 as_bad (_("Pre-increment mode is not valid for 68HC11"));
fafb6d17 1116 /* Backtrack. */
60bcf0fa
NC
1117 if (which == 0 && opmode & M6812_OP_IDX_P2
1118 && reg != REG_X && reg != REG_Y
1119 && reg != REG_PC && reg != REG_SP)
1120 {
1121 reg = REG_NONE;
1122 input_line_pointer = p;
1123 }
1124
1125 if (reg == REG_NONE && mode != M6811_OP_DIRECT
1126 && !(mode == M6811_OP_NONE && opmode & M6811_OP_IND16))
1127 {
1128 as_bad (_("Wrong register in register indirect mode."));
1129 return -1;
1130 }
1131 if (mode == M6812_OP_IDX_2)
1132 {
1133 p = skip_whites (input_line_pointer);
1134 if (*p++ != ']')
1135 {
1136 as_bad (_("Missing `]' to close register indirect operand."));
1137 return -1;
1138 }
1139 input_line_pointer = p;
1140 }
1141 if (reg != REG_NONE)
1142 {
1143 oper->reg1 = reg;
1144 if (mode == M6811_OP_NONE)
1145 {
1146 p = input_line_pointer;
1147 if (*p == '-')
1148 {
1149 mode = M6812_POST_DEC;
1150 p++;
1151 if (current_architecture & cpu6811)
1152 as_bad
1153 (_("Post-decrement mode is not valid for 68HC11."));
1154 }
1155 else if (*p == '+')
1156 {
1157 mode = M6812_POST_INC;
1158 p++;
1159 if (current_architecture & cpu6811)
1160 as_bad
1161 (_("Post-increment mode is not valid for 68HC11."));
1162 }
1163 else
1164 mode = M6812_OP_IDX;
1165
1166 input_line_pointer = p;
1167 }
1168 else
1169 mode |= M6812_OP_IDX;
1170
1171 oper->mode = mode;
1172 return 1;
1173 }
1174 }
1175
1176 if (mode == M6812_OP_D_IDX_2)
1177 {
1178 as_bad (_("Invalid indexed indirect mode."));
1179 return -1;
1180 }
1181 }
1182
1183 /* If the mode is not known until now, this is either a label
1184 or an indirect address. */
1185 if (mode == M6811_OP_NONE)
fafb6d17 1186 mode = M6811_OP_IND16 | M6811_OP_JUMP_REL;
60bcf0fa
NC
1187
1188 p = input_line_pointer;
1189 while (*p == ' ' || *p == '\t')
1190 p++;
1191 input_line_pointer = p;
1192 oper->mode = mode;
1193
1194 return 1;
1195}
1196
1197#define M6812_AUTO_INC_DEC (M6812_PRE_INC | M6812_PRE_DEC \
1198 | M6812_POST_INC | M6812_POST_DEC)
1199
1200/* Checks that the number 'num' fits for a given mode. */
1201static int
1202check_range (num, mode)
1203 long num;
1204 int mode;
1205{
1206 /* Auto increment and decrement are ok for [-8..8] without 0. */
1207 if (mode & M6812_AUTO_INC_DEC)
fafb6d17 1208 return (num != 0 && num <= 8 && num >= -8);
60bcf0fa
NC
1209
1210 /* The 68HC12 supports 5, 9 and 16-bits offsets. */
1211 if (mode & (M6812_INDEXED_IND | M6812_INDEXED | M6812_OP_IDX))
fafb6d17 1212 mode = M6811_OP_IND16;
60bcf0fa
NC
1213
1214 if (mode & M6812_OP_JUMP_REL16)
1215 mode = M6811_OP_IND16;
1216
1217 switch (mode)
1218 {
1219 case M6811_OP_IX:
1220 case M6811_OP_IY:
1221 case M6811_OP_DIRECT:
1222 return (num >= 0 && num <= 255) ? 1 : 0;
1223
1224 case M6811_OP_BITMASK:
1225 case M6811_OP_IMM8:
1226 return (((num & 0xFFFFFF00) == 0) || ((num & 0xFFFFFF00) == 0xFFFFFF00))
1227 ? 1 : 0;
1228
1229 case M6811_OP_JUMP_REL:
1230 return (num >= -128 && num <= 127) ? 1 : 0;
1231
1232 case M6811_OP_IND16:
1233 case M6811_OP_IMM16:
1234 return (((num & 0xFFFF0000) == 0) || ((num & 0xFFFF0000) == 0xFFFF0000))
1235 ? 1 : 0;
1236
1237 case M6812_OP_IBCC_MARKER:
1238 case M6812_OP_TBCC_MARKER:
1239 case M6812_OP_DBCC_MARKER:
1240 return (num >= -256 && num <= 255) ? 1 : 0;
1241
1242 case M6812_OP_TRAP_ID:
1243 return ((num >= 0x30 && num <= 0x39)
1244 || (num >= 0x40 && num <= 0x0ff)) ? 1 : 0;
1245
1246 default:
1247 return 0;
1248 }
1249}
60bcf0fa
NC
1250\f
1251/* Gas fixup generation. */
1252
1253/* Put a 1 byte expression described by 'oper'. If this expression contains
1254 unresolved symbols, generate an 8-bit fixup. */
1255static void
1256fixup8 (oper, mode, opmode)
1257 expressionS *oper;
1258 int mode;
1259 int opmode;
1260{
1261 char *f;
1262
1263 f = frag_more (1);
1264
1265 if (oper->X_op == O_constant)
1266 {
1267 if (mode & M6812_OP_TRAP_ID
1268 && !check_range (oper->X_add_number, M6812_OP_TRAP_ID))
1269 {
1270 static char trap_id_warn_once = 0;
1271
1272 as_bad (_("Trap id `%ld' is out of range."), oper->X_add_number);
1273 if (trap_id_warn_once == 0)
1274 {
1275 trap_id_warn_once = 1;
1276 as_bad (_("Trap id must be within [0x30..0x39] or [0x40..0xff]."));
1277 }
1278 }
1279
1280 if (!(mode & M6812_OP_TRAP_ID)
1281 && !check_range (oper->X_add_number, mode))
1282 {
1283 as_bad (_("Operand out of 8-bit range: `%ld'."), oper->X_add_number);
1284 }
1285 number_to_chars_bigendian (f, oper->X_add_number & 0x0FF, 1);
1286 }
1287 else if (oper->X_op != O_register)
1288 {
1289 if (mode & M6812_OP_TRAP_ID)
1290 as_bad (_("The trap id must be a constant."));
1291
1292 if (mode == M6811_OP_JUMP_REL)
1293 {
1294 fixS *fixp;
1295
1296 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
1297 oper, true, BFD_RELOC_8_PCREL);
1298 fixp->fx_pcrel_adjust = 1;
1299 }
1300 else
1301 {
1302 /* Now create an 8-bit fixup. If there was some %hi or %lo
1303 modifier, generate the reloc accordingly. */
1304 fix_new_exp (frag_now, f - frag_now->fr_literal, 1,
1305 oper, false,
1306 ((opmode & M6811_OP_HIGH_ADDR)
1307 ? BFD_RELOC_M68HC11_HI8
1308 : ((opmode & M6811_OP_LOW_ADDR)
1309 ? BFD_RELOC_M68HC11_LO8 : BFD_RELOC_8)));
1310 }
1311 number_to_chars_bigendian (f, 0, 1);
1312 }
1313 else
1314 {
1315 as_fatal (_("Operand `%x' not recognized in fixup8."), oper->X_op);
1316 }
1317}
1318
1319/* Put a 2 bytes expression described by 'oper'. If this expression contains
1320 unresolved symbols, generate a 16-bit fixup. */
1321static void
1322fixup16 (oper, mode, opmode)
1323 expressionS *oper;
1324 int mode;
1325 int opmode ATTRIBUTE_UNUSED;
1326{
1327 char *f;
1328
1329 f = frag_more (2);
1330
1331 if (oper->X_op == O_constant)
1332 {
1333 if (!check_range (oper->X_add_number, mode))
1334 {
1335 as_bad (_("Operand out of 16-bit range: `%ld'."),
fafb6d17 1336 oper->X_add_number);
60bcf0fa
NC
1337 }
1338 number_to_chars_bigendian (f, oper->X_add_number & 0x0FFFF, 2);
1339 }
1340 else if (oper->X_op != O_register)
1341 {
1342 fixS *fixp;
1343
1344 /* Now create a 16-bit fixup. */
1345 fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 2,
1346 oper,
1347 (mode & M6812_OP_JUMP_REL16 ? true : false),
1348 (mode & M6812_OP_JUMP_REL16
1349 ? BFD_RELOC_16_PCREL : BFD_RELOC_16));
1350 number_to_chars_bigendian (f, 0, 2);
1351 if (mode & M6812_OP_JUMP_REL16)
1352 fixp->fx_pcrel_adjust = 2;
1353 }
1354 else
1355 {
1356 as_fatal (_("Operand `%x' not recognized in fixup16."), oper->X_op);
1357 }
1358}
60bcf0fa
NC
1359\f
1360/* 68HC11 and 68HC12 code generation. */
1361
1362/* Translate the short branch/bsr instruction into a long branch. */
1363static unsigned char
1364convert_branch (code)
1365 unsigned char code;
1366{
1367 if (IS_OPCODE (code, M6812_BSR))
1368 return M6812_JSR;
1369 else if (IS_OPCODE (code, M6811_BSR))
1370 return M6811_JSR;
1371 else if (IS_OPCODE (code, M6811_BRA))
1372 return (current_architecture & cpu6812) ? M6812_JMP : M6811_JMP;
1373 else
1374 as_fatal (_("Unexpected branch conversion with `%x'"), code);
1375
1376 /* Keep gcc happy. */
1377 return M6811_JSR;
1378}
1379
1380/* Start a new insn that contains at least 'size' bytes. Record the
1381 line information of that insn in the dwarf2 debug sections. */
fafb6d17 1382static char *
60bcf0fa
NC
1383m68hc11_new_insn (size)
1384 int size;
1385{
fafb6d17 1386 char *f;
60bcf0fa
NC
1387
1388 f = frag_more (size);
1389
4dc7ead9 1390 dwarf2_emit_insn (size);
fafb6d17 1391
60bcf0fa
NC
1392 return f;
1393}
1394
1395/* Builds a jump instruction (bra, bcc, bsr). */
1396static void
1397build_jump_insn (opcode, operands, nb_operands, jmp_mode)
1398 struct m68hc11_opcode *opcode;
1399 operand operands[];
1400 int nb_operands;
1401 int jmp_mode;
1402{
1403 unsigned char code;
1404 int insn_size;
1405 char *f;
1406 unsigned long n;
1407
1408 /* The relative branch convertion is not supported for
1409 brclr and brset. */
1410 assert ((opcode->format & M6811_OP_BITMASK) == 0);
1411 assert (nb_operands == 1);
1412 assert (operands[0].reg1 == REG_NONE && operands[0].reg2 == REG_NONE);
1413
1414 code = opcode->opcode;
1415 insn_size = 1;
1416
1417 n = operands[0].exp.X_add_number;
1418
1419 /* Turn into a long branch:
1420 - when force long branch option (and not for jbcc pseudos),
1421 - when jbcc and the constant is out of -128..127 range,
1422 - when branch optimization is allowed and branch out of range. */
1423 if ((jmp_mode == 0 && flag_force_long_jumps)
1424 || (operands[0].exp.X_op == O_constant
1425 && (!check_range (n, opcode->format) &&
1426 (jmp_mode == 1 || flag_fixed_branchs == 0))))
1427 {
1428 if (code == M6811_BSR || code == M6811_BRA || code == M6812_BSR)
1429 {
1430 code = convert_branch (code);
1431
1432 f = m68hc11_new_insn (1);
1433 number_to_chars_bigendian (f, code, 1);
1434 }
1435 else if (current_architecture & cpu6812)
1436 {
1437 /* 68HC12: translate the bcc into a lbcc. */
1438 f = m68hc11_new_insn (2);
1439 number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1);
1440 number_to_chars_bigendian (f + 1, code, 1);
1441 fixup16 (&operands[0].exp, M6812_OP_JUMP_REL16,
1442 M6812_OP_JUMP_REL16);
1443 return;
1444 }
1445 else
1446 {
1447 /* 68HC11: translate the bcc into b!cc +3; jmp <L>. */
1448 f = m68hc11_new_insn (3);
1449 code ^= 1;
1450 number_to_chars_bigendian (f, code, 1);
1451 number_to_chars_bigendian (f + 1, 3, 1);
1452 number_to_chars_bigendian (f + 2, M6811_JMP, 1);
1453 }
1454 fixup16 (&operands[0].exp, M6811_OP_IND16, M6811_OP_IND16);
1455 return;
1456 }
1457
1458 /* Branch with a constant that must fit in 8-bits. */
1459 if (operands[0].exp.X_op == O_constant)
1460 {
1461 if (!check_range (n, opcode->format))
1462 {
1463 as_bad (_("Operand out of range for a relative branch: `%ld'"),
1464 n);
1465 }
1466 else if (opcode->format & M6812_OP_JUMP_REL16)
1467 {
1468 f = m68hc11_new_insn (4);
1469 number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1);
1470 number_to_chars_bigendian (f + 1, code, 1);
1471 number_to_chars_bigendian (f + 2, n & 0x0ffff, 2);
1472 }
1473 else
1474 {
1475 f = m68hc11_new_insn (2);
1476 number_to_chars_bigendian (f, code, 1);
1477 number_to_chars_bigendian (f + 1, n & 0x0FF, 1);
1478 }
1479 }
1480 else if (opcode->format & M6812_OP_JUMP_REL16)
1481 {
1482 f = m68hc11_new_insn (2);
1483 number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1);
1484 number_to_chars_bigendian (f + 1, code, 1);
1485 fixup16 (&operands[0].exp, M6812_OP_JUMP_REL16, M6812_OP_JUMP_REL16);
1486 }
1487 else
1488 {
1489 char *opcode;
1490
1491 /* Branch offset must fit in 8-bits, don't do some relax. */
1492 if (jmp_mode == 0 && flag_fixed_branchs)
1493 {
1494 opcode = m68hc11_new_insn (1);
1495 number_to_chars_bigendian (opcode, code, 1);
1496 fixup8 (&operands[0].exp, M6811_OP_JUMP_REL, M6811_OP_JUMP_REL);
1497 }
1498
1499 /* bra/bsr made be changed into jmp/jsr. */
1500 else if (code == M6811_BSR || code == M6811_BRA || code == M6812_BSR)
1501 {
1502 opcode = m68hc11_new_insn (2);
1503 number_to_chars_bigendian (opcode, code, 1);
1504 number_to_chars_bigendian (opcode + 1, 0, 1);
df86943d 1505 frag_var (rs_machine_dependent, 2, 1,
60bcf0fa
NC
1506 ENCODE_RELAX (STATE_PC_RELATIVE, STATE_UNDF),
1507 operands[0].exp.X_add_symbol, (offsetT) n, opcode);
1508 }
1509 else if (current_architecture & cpu6812)
1510 {
1511 opcode = m68hc11_new_insn (2);
1512 number_to_chars_bigendian (opcode, code, 1);
1513 number_to_chars_bigendian (opcode + 1, 0, 1);
1514 frag_var (rs_machine_dependent, 2, 2,
1515 ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_UNDF),
1516 operands[0].exp.X_add_symbol, (offsetT) n, opcode);
1517 }
1518 else
1519 {
1520 opcode = m68hc11_new_insn (2);
1521 number_to_chars_bigendian (opcode, code, 1);
1522 number_to_chars_bigendian (opcode + 1, 0, 1);
1523 frag_var (rs_machine_dependent, 3, 3,
1524 ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_UNDF),
1525 operands[0].exp.X_add_symbol, (offsetT) n, opcode);
1526 }
1527 }
1528}
1529
1530/* Builds a dbne/dbeq/tbne/tbeq instruction. */
1531static void
1532build_dbranch_insn (opcode, operands, nb_operands, jmp_mode)
1533 struct m68hc11_opcode *opcode;
1534 operand operands[];
1535 int nb_operands;
1536 int jmp_mode;
1537{
1538 unsigned char code;
1539 int insn_size;
1540 char *f;
1541 unsigned long n;
1542
1543 /* The relative branch convertion is not supported for
1544 brclr and brset. */
1545 assert ((opcode->format & M6811_OP_BITMASK) == 0);
1546 assert (nb_operands == 2);
1547 assert (operands[0].reg1 != REG_NONE);
1548
1549 code = opcode->opcode & 0x0FF;
1550 insn_size = 1;
1551
1552 f = m68hc11_new_insn (1);
1553 number_to_chars_bigendian (f, code, 1);
1554
1555 n = operands[1].exp.X_add_number;
1556 code = operands[0].reg1;
1557
1558 if (operands[0].reg1 == REG_NONE || operands[0].reg1 == REG_CCR
1559 || operands[0].reg1 == REG_PC)
1560 as_bad (_("Invalid register for dbcc/tbcc instruction."));
1561
1562 if (opcode->format & M6812_OP_IBCC_MARKER)
1563 code |= 0x80;
1564 else if (opcode->format & M6812_OP_TBCC_MARKER)
1565 code |= 0x40;
1566
1567 if (!(opcode->format & M6812_OP_EQ_MARKER))
1568 code |= 0x20;
1569
1570 /* Turn into a long branch:
1571 - when force long branch option (and not for jbcc pseudos),
1572 - when jdbcc and the constant is out of -256..255 range,
1573 - when branch optimization is allowed and branch out of range. */
1574 if ((jmp_mode == 0 && flag_force_long_jumps)
1575 || (operands[1].exp.X_op == O_constant
1576 && (!check_range (n, M6812_OP_IBCC_MARKER) &&
1577 (jmp_mode == 1 || flag_fixed_branchs == 0))))
1578 {
1579 f = frag_more (2);
1580 code ^= 0x20;
1581 number_to_chars_bigendian (f, code, 1);
1582 number_to_chars_bigendian (f + 1, M6812_JMP, 1);
1583 fixup16 (&operands[0].exp, M6811_OP_IND16, M6811_OP_IND16);
1584 return;
1585 }
1586
1587 /* Branch with a constant that must fit in 9-bits. */
1588 if (operands[1].exp.X_op == O_constant)
1589 {
1590 if (!check_range (n, M6812_OP_IBCC_MARKER))
1591 {
1592 as_bad (_("Operand out of range for a relative branch: `%ld'"),
1593 n);
1594 }
1595 else
1596 {
1597 if ((long) n < 0)
1598 code |= 0x10;
1599
1600 f = frag_more (2);
1601 number_to_chars_bigendian (f, code, 1);
1602 number_to_chars_bigendian (f + 1, n & 0x0FF, 1);
1603 }
1604 }
1605 else
1606 {
1607 /* Branch offset must fit in 8-bits, don't do some relax. */
1608 if (jmp_mode == 0 && flag_fixed_branchs)
1609 {
1610 fixup8 (&operands[0].exp, M6811_OP_JUMP_REL, M6811_OP_JUMP_REL);
1611 }
1612
1613 else
1614 {
1615 f = frag_more (2);
1616 number_to_chars_bigendian (f, code, 1);
1617 number_to_chars_bigendian (f + 1, 0, 1);
1618 frag_var (rs_machine_dependent, 3, 3,
1619 ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_UNDF),
1620 operands[1].exp.X_add_symbol, (offsetT) n, f);
1621 }
1622 }
1623}
1624
1625#define OP_EXTENDED (M6811_OP_PAGE2 | M6811_OP_PAGE3 | M6811_OP_PAGE4)
1626
1627/* Assemble the post index byte for 68HC12 extended addressing modes. */
1628static int
1629build_indexed_byte (op, format, move_insn)
1630 operand *op;
1631 int format ATTRIBUTE_UNUSED;
1632 int move_insn;
1633{
1634 unsigned char byte = 0;
1635 char *f;
1636 int mode;
1637 long val;
1638
1639 val = op->exp.X_add_number;
1640 mode = op->mode;
1641 if (mode & M6812_AUTO_INC_DEC)
1642 {
1643 byte = 0x20;
1644 if (mode & (M6812_POST_INC | M6812_POST_DEC))
1645 byte |= 0x10;
1646
1647 if (op->exp.X_op == O_constant)
1648 {
1649 if (!check_range (val, mode))
1650 {
1651 as_bad (_("Increment/decrement value is out of range: `%ld'."),
fafb6d17 1652 val);
60bcf0fa
NC
1653 }
1654 if (mode & (M6812_POST_INC | M6812_PRE_INC))
1655 byte |= (val - 1) & 0x07;
1656 else
1657 byte |= (8 - ((val) & 7)) | 0x8;
1658 }
1659 switch (op->reg1)
1660 {
1661 case REG_NONE:
1662 as_fatal (_("Expecting a register."));
1663
1664 case REG_X:
1665 byte |= 0;
1666 break;
1667
1668 case REG_Y:
1669 byte |= 0x40;
1670 break;
1671
1672 case REG_SP:
1673 byte |= 0x80;
1674 break;
1675
1676 default:
1677 as_bad (_("Invalid register for post/pre increment."));
1678 break;
1679 }
1680
1681 f = frag_more (1);
1682 number_to_chars_bigendian (f, byte, 1);
1683 return 1;
1684 }
1685
1686 if (mode & M6812_OP_IDX)
1687 {
1688 switch (op->reg1)
1689 {
1690 case REG_X:
1691 byte = 0;
1692 break;
1693
1694 case REG_Y:
1695 byte = 1;
1696 break;
1697
1698 case REG_SP:
1699 byte = 2;
1700 break;
1701
1702 case REG_PC:
1703 byte = 3;
1704 break;
1705
1706 default:
1707 as_bad (_("Invalid register."));
1708 break;
1709 }
1710 if (op->exp.X_op == O_constant)
1711 {
1712 if (!check_range (val, M6812_OP_IDX))
1713 {
1714 as_bad (_("Offset out of 16-bit range: %ld."), val);
1715 }
1716
1717 if (move_insn && !(val >= -16 && val <= 15))
1718 {
ae3e85dd
SC
1719 as_bad (_("Offset out of 5-bit range for movw/movb insn: %ld."),
1720 val);
60bcf0fa
NC
1721 return -1;
1722 }
1723
1724 if (val >= -16 && val <= 15 && !(mode & M6812_OP_IDX_2))
1725 {
1726 byte = byte << 6;
1727 byte |= val & 0x1f;
1728 f = frag_more (1);
1729 number_to_chars_bigendian (f, byte, 1);
1730 return 1;
1731 }
1732 else if (val >= -256 && val <= 255 && !(mode & M6812_OP_IDX_2))
1733 {
1734 byte = byte << 3;
1735 byte |= 0xe0;
1736 if (val < 0)
1737 byte |= 0x1;
1738 f = frag_more (2);
1739 number_to_chars_bigendian (f, byte, 1);
1740 number_to_chars_bigendian (f + 1, val & 0x0FF, 1);
1741 return 2;
1742 }
1743 else
1744 {
1745 byte = byte << 3;
1746 if (mode & M6812_OP_IDX_2)
1747 byte |= 0xe3;
1748 else
1749 byte |= 0xe2;
1750
1751 f = frag_more (3);
1752 number_to_chars_bigendian (f, byte, 1);
1753 number_to_chars_bigendian (f + 1, val & 0x0FFFF, 2);
1754 return 3;
1755 }
1756 }
1757 f = frag_more (1);
1758 number_to_chars_bigendian (f, byte, 1);
fafb6d17
NC
1759#if 0
1760 fix_new_exp (frag_now, f - frag_now->fr_literal, 2,
1761 &op->exp, false, BFD_RELOC_16);
1762#endif
60bcf0fa
NC
1763 frag_var (rs_machine_dependent, 2, 2,
1764 ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_UNDF),
1765 op->exp.X_add_symbol, val, f);
1766 return 3;
1767 }
1768
1769 if (mode & M6812_OP_REG)
1770 {
1771 if (mode & M6812_OP_IDX_2)
1772 {
1773 if (op->reg1 != REG_D)
1774 as_bad (_("Expecting register D for indexed indirect mode."));
1775 if (move_insn)
1776 as_bad (_("Indexed indirect mode is not allowed for movb/movw."));
1777
1778 byte = 0xE7;
1779 }
1780 else
1781 {
1782 switch (op->reg1)
1783 {
1784 case REG_A:
1785 byte = 0xE4;
1786 break;
1787
1788 case REG_B:
1789 byte = 0xE5;
1790 break;
1791
1792 default:
1793 as_bad (_("Invalid accumulator register."));
1794
1795 case REG_D:
1796 byte = 0xE6;
1797 break;
1798 }
1799 }
1800 switch (op->reg2)
1801 {
1802 case REG_X:
1803 break;
1804
1805 case REG_Y:
1806 byte |= (1 << 3);
1807 break;
1808
1809 case REG_SP:
1810 byte |= (2 << 3);
1811 break;
1812
1813 case REG_PC:
1814 byte |= (3 << 3);
1815 break;
1816
1817 default:
1818 as_bad (_("Invalid indexed register."));
1819 break;
1820 }
1821 f = frag_more (1);
1822 number_to_chars_bigendian (f, byte, 1);
1823 return 1;
1824 }
1825
1826 as_fatal (_("Addressing mode not implemented yet."));
1827 return 0;
1828}
1829
1830/* Assemble the 68HC12 register mode byte. */
1831static int
1832build_reg_mode (op, format)
1833 operand *op;
1834 int format;
1835{
1836 unsigned char byte;
1837 char *f;
1838
1839 if (format & M6812_OP_SEX_MARKER
1840 && op->reg1 != REG_A && op->reg1 != REG_B && op->reg1 != REG_CCR)
1841 as_bad (_("Invalid source register for this instruction, use 'tfr'."));
1842 else if (op->reg1 == REG_NONE || op->reg1 == REG_PC)
1843 as_bad (_("Invalid source register."));
1844
1845 if (format & M6812_OP_SEX_MARKER
1846 && op->reg2 != REG_D
1847 && op->reg2 != REG_X && op->reg2 != REG_Y && op->reg2 != REG_SP)
1848 as_bad (_("Invalid destination register for this instruction, use 'tfr'."));
1849 else if (op->reg2 == REG_NONE || op->reg2 == REG_PC)
1850 as_bad (_("Invalid destination register."));
1851
1852 byte = (op->reg1 << 4) | (op->reg2);
1853 if (format & M6812_OP_EXG_MARKER)
1854 byte |= 0x80;
1855
1856 f = frag_more (1);
1857 number_to_chars_bigendian (f, byte, 1);
1858 return 1;
1859}
1860
1861/* build_insn takes a pointer to the opcode entry in the opcode table,
1862 the array of operand expressions and builds the correspding instruction.
1863 This operation only deals with non relative jumps insn (need special
1864 handling). */
1865static void
1866build_insn (opcode, operands, nb_operands)
1867 struct m68hc11_opcode *opcode;
1868 operand operands[];
1869 int nb_operands ATTRIBUTE_UNUSED;
1870{
1871 int i;
1872 char *f;
1873 int insn_size = 1;
1874 long format;
1875 int move_insn = 0;
1876
1877 /* Put the page code instruction if there is one. */
1878 format = opcode->format;
1879 if (format & OP_EXTENDED)
1880 {
1881 int page_code;
1882
1883 f = m68hc11_new_insn (2);
1884 if (format & M6811_OP_PAGE2)
1885 page_code = M6811_OPCODE_PAGE2;
1886 else if (format & M6811_OP_PAGE3)
1887 page_code = M6811_OPCODE_PAGE3;
1888 else
1889 page_code = M6811_OPCODE_PAGE4;
1890
1891 number_to_chars_bigendian (f, page_code, 1);
1892 f++;
1893 insn_size = 2;
1894 }
1895 else
1896 f = m68hc11_new_insn (1);
1897
1898 number_to_chars_bigendian (f, opcode->opcode, 1);
1899
1900 i = 0;
1901
1902 /* The 68HC12 movb and movw instructions are special. We have to handle
1903 them in a special way. */
1904 if (format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2))
1905 {
1906 move_insn = 1;
1907 if (format & M6812_OP_IDX)
1908 {
1909 insn_size += build_indexed_byte (&operands[0], format, 1);
1910 i = 1;
1911 format &= ~M6812_OP_IDX;
1912 }
1913 if (format & M6812_OP_IDX_P2)
1914 {
1915 insn_size += build_indexed_byte (&operands[1], format, 1);
1916 i = 0;
1917 format &= ~M6812_OP_IDX_P2;
1918 }
1919 }
1920
1921 if (format & (M6811_OP_DIRECT | M6811_OP_IMM8))
1922 {
1923 insn_size++;
1924 fixup8 (&operands[i].exp,
1925 format & (M6811_OP_DIRECT | M6811_OP_IMM8 | M6812_OP_TRAP_ID),
1926 operands[i].mode);
1927 i++;
1928 }
1929 else if (format & (M6811_OP_IMM16 | M6811_OP_IND16))
1930 {
1931 insn_size += 2;
1932 fixup16 (&operands[i].exp, format & (M6811_OP_IMM16 | M6811_OP_IND16),
1933 operands[i].mode);
1934 i++;
1935 }
1936 else if (format & (M6811_OP_IX | M6811_OP_IY))
1937 {
1938 if ((format & M6811_OP_IX) && (operands[0].reg1 != REG_X))
1939 as_bad (_("Invalid indexed register, expecting register X."));
1940 if ((format & M6811_OP_IY) && (operands[0].reg1 != REG_Y))
1941 as_bad (_("Invalid indexed register, expecting register Y."));
1942
1943 insn_size++;
1944 fixup8 (&operands[0].exp, M6811_OP_IX, operands[0].mode);
1945 i = 1;
1946 }
1947 else if (format &
1948 (M6812_OP_IDX | M6812_OP_IDX_2 | M6812_OP_IDX_1 | M6812_OP_D_IDX))
1949 {
1950 insn_size += build_indexed_byte (&operands[i], format, move_insn);
1951 i++;
1952 }
1953 else if (format & M6812_OP_REG && current_architecture & cpu6812)
1954 {
1955 insn_size += build_reg_mode (&operands[i], format);
1956 i++;
1957 }
1958 if (format & M6811_OP_BITMASK)
1959 {
1960 insn_size++;
1961 fixup8 (&operands[i].exp, M6811_OP_BITMASK, operands[i].mode);
1962 i++;
1963 }
1964 if (format & M6811_OP_JUMP_REL)
1965 {
1966 insn_size++;
1967 fixup8 (&operands[i].exp, M6811_OP_JUMP_REL, operands[i].mode);
1968 i++;
1969 }
1970 else if (format & M6812_OP_IND16_P2)
1971 {
1972 insn_size += 2;
1973 fixup16 (&operands[1].exp, M6811_OP_IND16, operands[1].mode);
1974 }
1975}
60bcf0fa
NC
1976\f
1977/* Opcode identification and operand analysis. */
1978
1979/* find() gets a pointer to an entry in the opcode table. It must look at all
1980 opcodes with the same name and use the operands to choose the correct
1981 opcode. Returns the opcode pointer if there was a match and 0 if none. */
1982static struct m68hc11_opcode *
1983find (opc, operands, nb_operands)
1984 struct m68hc11_opcode_def *opc;
1985 operand operands[];
1986 int nb_operands;
1987{
1988 int i, match, pos;
1989 struct m68hc11_opcode *opcode;
1990 struct m68hc11_opcode *op_indirect;
1991
1992 op_indirect = 0;
1993 opcode = opc->opcode;
1994
1995 /* Now search the opcode table table for one with operands
1996 that matches what we've got. We're only done if the operands matched so
1997 far AND there are no more to check. */
1998 for (pos = match = 0; match == 0 && pos < opc->nb_modes; pos++, opcode++)
1999 {
2000 int poss_indirect = 0;
2001 long format = opcode->format;
2002 int expect;
2003
2004 expect = 0;
2005 if (opcode->format & M6811_OP_MASK)
2006 expect++;
2007 if (opcode->format & M6811_OP_BITMASK)
2008 expect++;
2009 if (opcode->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
2010 expect++;
2011 if (opcode->format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2))
2012 expect++;
2013
2014 for (i = 0; expect == nb_operands && i < nb_operands; i++)
2015 {
2016 int mode = operands[i].mode;
2017
2018 if (mode & M6811_OP_IMM16)
2019 {
2020 if (format &
2021 (M6811_OP_IMM8 | M6811_OP_IMM16 | M6811_OP_BITMASK))
2022 continue;
2023 break;
2024 }
2025 if (mode == M6811_OP_DIRECT)
2026 {
2027 if (format & M6811_OP_DIRECT)
2028 continue;
2029
2030 /* If the operand is a page 0 operand, remember a
2031 possible <abs-16> addressing mode. We mark
2032 this and continue to check other operands. */
2033 if (format & M6811_OP_IND16
2034 && flag_strict_direct_addressing && op_indirect == 0)
2035 {
2036 poss_indirect = 1;
2037 continue;
2038 }
2039 break;
2040 }
2041 if (mode & M6811_OP_IND16)
2042 {
2043 if (i == 0 && (format & M6811_OP_IND16) != 0)
2044 continue;
2045 if (i != 0 && (format & M6812_OP_IND16_P2) != 0)
2046 continue;
2047 if (i == 0 && (format & M6811_OP_BITMASK))
2048 break;
2049 }
2050 if (mode & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
2051 {
2052 if (format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
2053 continue;
2054 }
2055 if (mode & M6812_OP_REG)
2056 {
df86943d
NC
2057 if (i == 0
2058 && (format & M6812_OP_REG)
2059 && (operands[i].reg2 == REG_NONE))
60bcf0fa 2060 continue;
df86943d
NC
2061 if (i == 0
2062 && (format & M6812_OP_REG)
2063 && (format & M6812_OP_REG_2)
2064 && (operands[i].reg2 != REG_NONE))
60bcf0fa 2065 continue;
df86943d
NC
2066 if (i == 0
2067 && (format & M6812_OP_IDX)
2068 && (operands[i].reg2 != REG_NONE))
2069 continue;
2070 if (i == 0
2071 && (format & M6812_OP_D_IDX))
2072 continue;
2073 if (i == 0
2074 && (format & M6812_OP_IDX)
60bcf0fa
NC
2075 && (format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2)))
2076 continue;
df86943d
NC
2077 if (i == 1
2078 && (format & M6812_OP_IDX_P2))
60bcf0fa
NC
2079 continue;
2080 break;
2081 }
2082 if (mode & M6812_OP_IDX)
2083 {
2084 if (format & M6811_OP_IX && operands[i].reg1 == REG_X)
2085 continue;
2086 if (format & M6811_OP_IY && operands[i].reg1 == REG_Y)
2087 continue;
2088 if (i == 0
2089 && format & (M6812_OP_IDX | M6812_OP_IDX_1 | M6812_OP_IDX_2)
2090 && (operands[i].reg1 == REG_X
2091 || operands[i].reg1 == REG_Y
2092 || operands[i].reg1 == REG_SP
2093 || operands[i].reg1 == REG_PC))
2094 continue;
2095 if (i == 1 && format & M6812_OP_IDX_P2)
2096 continue;
2097 }
2098 if (mode & M6812_AUTO_INC_DEC)
2099 {
2100 if (i == 0
2101 && format & (M6812_OP_IDX | M6812_OP_IDX_1 |
2102 M6812_OP_IDX_2))
2103 continue;
2104 if (i == 1 && format & M6812_OP_IDX_P2)
2105 continue;
2106 }
2107 break;
2108 }
2109 match = i == nb_operands;
2110
2111 /* Operands are ok but an operand uses page 0 addressing mode
2112 while the insn supports abs-16 mode. Keep a reference to this
2113 insns in case there is no insn supporting page 0 addressing. */
2114 if (match && poss_indirect)
2115 {
2116 op_indirect = opcode;
2117 match = 0;
2118 }
2119 if (match)
2120 break;
2121 }
2122
2123 /* Page 0 addressing is used but not supported by any insn.
2124 If absolute addresses are supported, we use that insn. */
2125 if (match == 0 && op_indirect)
2126 {
2127 opcode = op_indirect;
2128 match = 1;
2129 }
2130
2131 if (!match)
2132 {
2133 return (0);
2134 }
2135
2136 return opcode;
2137}
2138
60bcf0fa
NC
2139/* Find the real opcode and its associated operands. We use a progressive
2140 approach here. On entry, 'opc' points to the first opcode in the
2141 table that matches the opcode name in the source line. We try to
2142 isolate an operand, find a possible match in the opcode table.
2143 We isolate another operand if no match were found. The table 'operands'
2144 is filled while operands are recognized.
2145
2146 Returns the opcode pointer that matches the opcode name in the
2147 source line and the associated operands. */
2148static struct m68hc11_opcode *
2149find_opcode (opc, operands, nb_operands)
2150 struct m68hc11_opcode_def *opc;
2151 operand operands[];
2152 int *nb_operands;
2153{
2154 struct m68hc11_opcode *opcode;
2155 int i;
2156
2157 if (opc->max_operands == 0)
2158 {
2159 *nb_operands = 0;
2160 return opc->opcode;
2161 }
2162
2163 for (i = 0; i < opc->max_operands;)
2164 {
2165 int result;
2166
2167 result = get_operand (&operands[i], i, opc->format);
2168 if (result <= 0)
fafb6d17 2169 return 0;
60bcf0fa
NC
2170
2171 /* Special case where the bitmask of the bclr/brclr
2172 instructions is not introduced by #.
2173 Example: bclr 3,x $80. */
2174 if (i == 1 && (opc->format & M6811_OP_BITMASK)
2175 && (operands[i].mode & M6811_OP_IND16))
2176 {
2177 operands[i].mode = M6811_OP_IMM16;
2178 }
2179
2180 i += result;
2181 *nb_operands = i;
2182 if (i >= opc->min_operands)
2183 {
2184 opcode = find (opc, operands, i);
2185 if (opcode)
fafb6d17 2186 return opcode;
60bcf0fa
NC
2187 }
2188
2189 if (*input_line_pointer == ',')
2190 input_line_pointer++;
2191 }
82efde3a 2192
60bcf0fa
NC
2193 return 0;
2194}
2195
2196#define M6812_XBCC_MARKER (M6812_OP_TBCC_MARKER \
2197 | M6812_OP_DBCC_MARKER \
2198 | M6812_OP_IBCC_MARKER)
60bcf0fa
NC
2199\f
2200/* Gas line assembler entry point. */
2201
2202/* This is the main entry point for the machine-dependent assembler. str
2203 points to a machine-dependent instruction. This function is supposed to
2204 emit the frags/bytes it assembles to. */
2205void
2206md_assemble (str)
2207 char *str;
2208{
2209 struct m68hc11_opcode_def *opc;
2210 struct m68hc11_opcode *opcode;
2211
2212 unsigned char *op_start, *save;
2213 unsigned char *op_end;
2214 char name[20];
2215 int nlen = 0;
2216 operand operands[M6811_MAX_OPERANDS];
2217 int nb_operands;
2218 int branch_optimize = 0;
2219 int alias_id = -1;
2220
fafb6d17 2221 /* Drop leading whitespace. */
60bcf0fa
NC
2222 while (*str == ' ')
2223 str++;
2224
2225 /* Find the opcode end and get the opcode in 'name'. The opcode is forced
2226 lower case (the opcode table only has lower case op-codes). */
2227 for (op_start = op_end = (unsigned char *) (str);
2228 *op_end && nlen < 20 && !is_end_of_line[*op_end] && *op_end != ' ';
2229 op_end++)
2230 {
2231 name[nlen] = tolower (op_start[nlen]);
2232 nlen++;
2233 }
2234 name[nlen] = 0;
2235
2236 if (nlen == 0)
2237 {
2238 as_bad (_("No instruction or missing opcode."));
2239 return;
2240 }
2241
2242 /* Find the opcode definition given its name. */
2243 opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash, name);
2244
2245 /* If it's not recognized, look for 'jbsr' and 'jbxx'. These are
2246 pseudo insns for relative branch. For these branchs, we always
2247 optimize them (turned into absolute branchs) even if --short-branchs
2248 is given. */
2249 if (opc == NULL && name[0] == 'j' && name[1] == 'b')
2250 {
2251 opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash, &name[1]);
2252 if (opc
2253 && (!(opc->format & M6811_OP_JUMP_REL)
2254 || (opc->format & M6811_OP_BITMASK)))
2255 opc = 0;
2256 if (opc)
2257 branch_optimize = 1;
2258 }
2259
2260 /* The following test should probably be removed. This is not conform
2261 to Motorola assembler specs. */
2262 if (opc == NULL && flag_mri)
2263 {
2264 if (*op_end == ' ' || *op_end == '\t')
2265 {
2266 while (*op_end == ' ' || *op_end == '\t')
2267 op_end++;
2268
2269 if (nlen < 19
2270 && (*op_end &&
2271 (is_end_of_line[op_end[1]]
2272 || op_end[1] == ' ' || op_end[1] == '\t'
2273 || !isalnum (op_end[1])))
2274 && (*op_end == 'a' || *op_end == 'b'
2275 || *op_end == 'A' || *op_end == 'B'
2276 || *op_end == 'd' || *op_end == 'D'
2277 || *op_end == 'x' || *op_end == 'X'
2278 || *op_end == 'y' || *op_end == 'Y'))
2279 {
2280 name[nlen++] = tolower (*op_end++);
2281 name[nlen] = 0;
2282 opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash,
2283 name);
2284 }
2285 }
2286 }
2287
2288 /* Identify a possible instruction alias. There are some on the
2289 68HC12 to emulate a fiew 68HC11 instructions. */
2290 if (opc == NULL && (current_architecture & cpu6812))
2291 {
2292 int i;
2293
2294 for (i = 0; i < m68hc12_num_alias; i++)
2295 if (strcmp (m68hc12_alias[i].name, name) == 0)
2296 {
2297 alias_id = i;
2298 break;
2299 }
2300 }
2301 if (opc == NULL && alias_id < 0)
2302 {
2303 as_bad (_("Opcode `%s' is not recognized."), name);
2304 return;
2305 }
2306 save = input_line_pointer;
2307 input_line_pointer = op_end;
2308
2309 if (opc)
2310 {
2311 opc->used++;
2312 opcode = find_opcode (opc, operands, &nb_operands);
2313 }
2314 else
2315 opcode = 0;
2316
2317 if ((opcode || alias_id >= 0) && !flag_mri)
2318 {
2319 char *p = input_line_pointer;
2320
2321 while (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r')
2322 p++;
2323
2324 if (*p != '\n' && *p)
2325 as_bad (_("Garbage at end of instruction: `%s'."), p);
2326 }
2327
2328 input_line_pointer = save;
2329
2330 if (alias_id >= 0)
2331 {
2332 char *f = m68hc11_new_insn (m68hc12_alias[alias_id].size);
fafb6d17 2333
60bcf0fa
NC
2334 number_to_chars_bigendian (f, m68hc12_alias[alias_id].code1, 1);
2335 if (m68hc12_alias[alias_id].size > 1)
2336 number_to_chars_bigendian (f + 1, m68hc12_alias[alias_id].code2, 1);
2337
2338 return;
2339 }
2340
2341 /* Opcode is known but does not have valid operands. Print out the
2342 syntax for this opcode. */
2343 if (opcode == 0)
2344 {
2345 if (flag_print_insn_syntax)
2346 print_insn_format (name);
2347
2348 as_bad (_("Invalid operand for `%s'"), name);
2349 return;
2350 }
2351
2352 /* Treat dbeq/ibeq/tbeq instructions in a special way. The branch is
2353 relative and must be in the range -256..255 (9-bits). */
2354 if ((opcode->format & M6812_XBCC_MARKER)
2355 && (opcode->format & M6811_OP_JUMP_REL))
2356 build_dbranch_insn (opcode, operands, nb_operands);
2357
2358 /* Relative jumps instructions are taken care of separately. We have to make
2359 sure that the relative branch is within the range -128..127. If it's out
2360 of range, the instructions are changed into absolute instructions.
2361 This is not supported for the brset and brclr instructions. */
2362 else if ((opcode->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
2363 && !(opcode->format & M6811_OP_BITMASK))
2364 build_jump_insn (opcode, operands, nb_operands, branch_optimize);
2365 else
2366 build_insn (opcode, operands, nb_operands);
2367}
60bcf0fa
NC
2368\f
2369/* Relocation, relaxation and frag conversions. */
60bcf0fa
NC
2370long
2371md_pcrel_from_section (fixp, sec)
2372 fixS *fixp;
2373 segT sec;
2374{
2375 int adjust;
2376 if (fixp->fx_addsy != (symbolS *) NULL
2377 && (!S_IS_DEFINED (fixp->fx_addsy)
fafb6d17 2378 || (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
60bcf0fa
NC
2379 return 0;
2380
2381 adjust = fixp->fx_pcrel_adjust;
2382 return fixp->fx_frag->fr_address + fixp->fx_where + adjust;
2383}
2384
2385/* If while processing a fixup, a reloc really needs to be created
2386 then it is done here. */
2387arelent *
2388tc_gen_reloc (section, fixp)
2389 asection *section;
2390 fixS *fixp;
2391{
2392 arelent *reloc;
2393
2394 reloc = (arelent *) xmalloc (sizeof (arelent));
2395 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
2396 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
2397 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
2398 if (fixp->fx_r_type == 0)
2399 reloc->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_16);
2400 else
2401 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
2402 if (reloc->howto == (reloc_howto_type *) NULL)
2403 {
2404 as_bad_where (fixp->fx_file, fixp->fx_line,
2405 _("Relocation %d is not supported by object file format."),
2406 (int) fixp->fx_r_type);
2407 return NULL;
2408 }
2409
2410 if (!fixp->fx_pcrel)
2411 reloc->addend = fixp->fx_addnumber;
2412 else
2413 reloc->addend = (section->vma
2414 + (fixp->fx_pcrel_adjust == 64
2415 ? -1 : fixp->fx_pcrel_adjust)
2416 + fixp->fx_addnumber
2417 + md_pcrel_from_section (fixp, section));
2418 return reloc;
2419}
2420
2421void
2422md_convert_frag (abfd, sec, fragP)
2423 bfd *abfd ATTRIBUTE_UNUSED;
2424 asection *sec ATTRIBUTE_UNUSED;
2425 fragS *fragP;
2426{
2427 fixS *fixp;
2428 long disp;
2429 char *buffer_address = fragP->fr_literal;
2430
2431 /* Address in object code of the displacement. */
2432 register int object_address = fragP->fr_fix + fragP->fr_address;
2433
2434 buffer_address += fragP->fr_fix;
2435
2436 /* The displacement of the address, from current location. */
2437 disp = fragP->fr_symbol ? S_GET_VALUE (fragP->fr_symbol) : 0;
2438 disp = (disp + fragP->fr_offset) - object_address;
2439 disp += symbol_get_frag (fragP->fr_symbol)->fr_address;
2440
2441 switch (fragP->fr_subtype)
2442 {
2443 case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE):
2444 fragP->fr_opcode[1] = disp;
2445 break;
2446
2447 case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD):
2448 /* This relax is only for bsr and bra. */
2449 assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
2450 || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
2451 || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
2452
2453 fragP->fr_opcode[0] = convert_branch (fragP->fr_opcode[0]);
2454
2455 fix_new (fragP, fragP->fr_fix - 1, 2,
2456 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
2457 fragP->fr_fix += 1;
2458 break;
2459
2460 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_BYTE):
2461 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_BYTE):
2462 fragP->fr_opcode[1] = disp;
2463 break;
2464
2465 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_WORD):
2466 /* Invert branch. */
2467 fragP->fr_opcode[0] ^= 1;
fafb6d17 2468 fragP->fr_opcode[1] = 3; /* Branch offset. */
60bcf0fa
NC
2469 buffer_address[0] = M6811_JMP;
2470 fix_new (fragP, fragP->fr_fix + 1, 2,
2471 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
2472 fragP->fr_fix += 3;
2473 break;
2474
2475 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_WORD):
2476 /* Translate branch into a long branch. */
2477 fragP->fr_opcode[1] = fragP->fr_opcode[0];
2478 fragP->fr_opcode[0] = M6811_OPCODE_PAGE2;
2479
2480 fixp = fix_new (fragP, fragP->fr_fix, 2,
2481 fragP->fr_symbol, fragP->fr_offset, 1,
2482 BFD_RELOC_16_PCREL);
2483 fixp->fx_pcrel_adjust = 2;
2484 fragP->fr_fix += 2;
2485 break;
2486
2487 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS5):
2488 fragP->fr_opcode[0] = fragP->fr_opcode[0] << 5;
2489 fragP->fr_opcode[0] |= disp & 0x1f;
2490 break;
2491
2492 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9):
2493 fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3);
2494 fragP->fr_opcode[0] |= 0xE0;
2495 fix_new (fragP, fragP->fr_fix + 1, 1,
2496 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_8);
2497 fragP->fr_fix += 1;
2498 break;
2499
2500 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16):
2501 fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3);
2502 fragP->fr_opcode[0] |= 0xE2;
2503 fix_new (fragP, fragP->fr_fix, 2,
2504 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
2505 fragP->fr_fix += 1;
2506 break;
2507
2508 case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_BYTE):
2509 if (disp < 0)
2510 fragP->fr_opcode[0] |= 0x10;
2511
2512 fragP->fr_opcode[1] = disp & 0x0FF;
2513 break;
2514
2515 case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_WORD):
2516 /* Invert branch. */
2517 fragP->fr_opcode[0] ^= 0x20;
2518 fragP->fr_opcode[1] = 3; /* Branch offset. */
2519 buffer_address[0] = M6812_JMP;
2520 fix_new (fragP, fragP->fr_fix + 1, 2,
2521 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
2522 fragP->fr_fix += 3;
2523 break;
2524
2525 default:
2526 break;
2527 }
2528}
2529
2530/* Force truly undefined symbols to their maximum size, and generally set up
2531 the frag list to be relaxed. */
2532int
2533md_estimate_size_before_relax (fragP, segment)
2534 fragS *fragP;
2535 asection *segment;
2536{
2537 int old_fr_fix;
2538 char *buffer_address = fragP->fr_fix + fragP->fr_literal;
2539
2540 old_fr_fix = fragP->fr_fix;
2541
2542 switch (fragP->fr_subtype)
2543 {
2544 case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_UNDF):
2545
2546 /* This relax is only for bsr and bra. */
2547 assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
2548 || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
2549 || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
2550
2551 /* A relaxable case. */
2552 if (S_GET_SEGMENT (fragP->fr_symbol) == segment)
2553 {
2554 fragP->fr_subtype = ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE);
2555 }
2556 else
2557 {
2558 if (flag_fixed_branchs)
2559 as_bad_where (fragP->fr_file, fragP->fr_line,
2560 _("bra or bsr with undefined symbol."));
2561
2562 /* The symbol is undefined or in a separate section. Turn bra into a
2563 jmp and bsr into a jsr. The insn becomes 3 bytes long (instead of
2564 2). A fixup is necessary for the unresolved symbol address. */
2565
2566 fragP->fr_opcode[0] = convert_branch (fragP->fr_opcode[0]);
2567
2568 fragP->fr_fix++;
2569 fix_new (fragP, old_fr_fix - 1, 2, fragP->fr_symbol,
2570 fragP->fr_offset, 0, BFD_RELOC_16);
2571 frag_wane (fragP);
2572 }
2573 break;
2574
2575 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_UNDF):
2576 assert (current_architecture & cpu6811);
2577
2578 if (S_GET_SEGMENT (fragP->fr_symbol) == segment)
2579 {
2580 fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH,
2581 STATE_BYTE);
2582 }
2583 else
2584 {
fafb6d17
NC
2585 fragP->fr_opcode[0] ^= 1; /* Reverse sense of branch. */
2586 fragP->fr_opcode[1] = 3; /* Skip next jmp insn (3 bytes). */
60bcf0fa
NC
2587
2588 /* Don't use fr_opcode[2] because this may be
2589 in a different frag. */
2590 buffer_address[0] = M6811_JMP;
2591
2592 fragP->fr_fix++;
2593 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
2594 fragP->fr_offset, 0, BFD_RELOC_16);
2595 fragP->fr_fix += 2;
2596 frag_wane (fragP);
2597 }
2598 break;
2599
2600 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_UNDF):
2601 assert (current_architecture & cpu6812);
2602
2603 if (S_GET_SEGMENT (fragP->fr_symbol) == segment)
2604 {
2605 fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_OFFSET,
2606 STATE_BITS5);
2607 }
2608 else
2609 {
2610 /* Switch the indexed operation to 16-bit mode. */
2611 if ((fragP->fr_opcode[1] & 0x21) == 0x20)
2612 fragP->fr_opcode[1] = (fragP->fr_opcode[1] >> 3) | 0xc0 | 0x02;
2613
2614 fragP->fr_fix++;
2615 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
2616 fragP->fr_offset, 0, BFD_RELOC_16);
2617 fragP->fr_fix += 2;
2618 frag_wane (fragP);
2619 }
2620 break;
2621
2622 case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_UNDF):
2623 assert (current_architecture & cpu6812);
2624
2625 if (S_GET_SEGMENT (fragP->fr_symbol) == segment)
2626 {
2627 fragP->fr_subtype = ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_BYTE);
2628 }
2629 else
2630 {
fafb6d17 2631 fragP->fr_opcode[0] ^= 0x20; /* Reverse sense of branch. */
60bcf0fa
NC
2632 fragP->fr_opcode[1] = 3; /* Skip next jmp insn (3 bytes). */
2633
2634 /* Don't use fr_opcode[2] because this may be
2635 in a different frag. */
2636 buffer_address[0] = M6812_JMP;
2637
2638 fragP->fr_fix++;
2639 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
2640 fragP->fr_offset, 0, BFD_RELOC_16);
2641 fragP->fr_fix += 2;
2642 frag_wane (fragP);
2643 }
2644 break;
2645
2646 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_UNDF):
2647 assert (current_architecture & cpu6812);
2648
2649 if (S_GET_SEGMENT (fragP->fr_symbol) == segment)
2650 {
2651 fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812,
2652 STATE_BYTE);
2653 }
2654 else
2655 {
2656 /* Translate into a lbcc branch. */
2657 fragP->fr_opcode[1] = fragP->fr_opcode[0];
2658 fragP->fr_opcode[0] = M6811_OPCODE_PAGE2;
2659
2660 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
2661 fragP->fr_offset, 0, BFD_RELOC_16_PCREL);
2662 fragP->fr_fix += 2;
2663 frag_wane (fragP);
2664 }
2665 break;
2666
2667 default:
2668 as_fatal (_("Subtype %d is not recognized."), fragP->fr_subtype);
2669 }
2670
2671 return (fragP->fr_fix - old_fr_fix);
2672}
2673
2674int
2675md_apply_fix (fixp, valuep)
2676 fixS *fixp;
2677 valueT *valuep;
2678{
2679 char *where;
2680 long value;
2681 int op_type;
2682
2683 if (fixp->fx_addsy == (symbolS *) NULL)
2684 {
2685 value = *valuep;
2686 fixp->fx_done = 1;
2687 }
2688 else if (fixp->fx_pcrel)
2689 {
2690 value = *valuep;
2691 }
2692 else
2693 {
2694 value = fixp->fx_offset;
2695 if (fixp->fx_subsy != (symbolS *) NULL)
2696 {
2697 if (S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
2698 {
2699 value -= S_GET_VALUE (fixp->fx_subsy);
2700 }
2701 else
2702 {
2703 /* We don't actually support subtracting a symbol. */
2704 as_bad_where (fixp->fx_file, fixp->fx_line,
2705 _("Expression too complex."));
2706 }
2707 }
2708 }
2709
2710 op_type = fixp->fx_r_type;
2711
2712 /* Patch the instruction with the resolved operand. Elf relocation
2713 info will also be generated to take care of linker/loader fixups.
2714 The 68HC11 addresses only 64Kb, we are only concerned by 8 and 16-bit
2715 relocs. BFD_RELOC_8 is basically used for .page0 access (the linker
2716 will warn for overflows). BFD_RELOC_8_PCREL should not be generated
2717 because it's either resolved or turned out into non-relative insns (see
2718 relax table, bcc, bra, bsr transformations)
2719
2720 The BFD_RELOC_32 is necessary for the support of --gstabs. */
2721 where = fixp->fx_frag->fr_literal + fixp->fx_where;
2722
2723 switch (fixp->fx_r_type)
2724 {
2725 case BFD_RELOC_32:
2726 bfd_putb32 ((bfd_vma) value, (unsigned char *) where);
2727 break;
2728
2729 case BFD_RELOC_16:
2730 case BFD_RELOC_16_PCREL:
2731 bfd_putb16 ((bfd_vma) value, (unsigned char *) where);
2732 if (value < -65537 || value > 65535)
2733 as_bad_where (fixp->fx_file, fixp->fx_line,
2734 _("Value out of 16-bit range."));
2735 break;
2736
2737 case BFD_RELOC_M68HC11_HI8:
2738 value = value >> 8;
fafb6d17 2739 /* Fall through. */
60bcf0fa
NC
2740
2741 case BFD_RELOC_M68HC11_LO8:
2742 case BFD_RELOC_8:
fafb6d17
NC
2743#if 0
2744 bfd_putb8 ((bfd_vma) value, (unsigned char *) where);
2745#endif
60bcf0fa
NC
2746 ((bfd_byte *) where)[0] = (bfd_byte) value;
2747 break;
2748
2749 case BFD_RELOC_8_PCREL:
fafb6d17
NC
2750#if 0
2751 bfd_putb8 ((bfd_vma) value, (unsigned char *) where);
2752#endif
60bcf0fa
NC
2753 ((bfd_byte *) where)[0] = (bfd_byte) value;
2754
2755 if (value < -128 || value > 127)
2756 as_bad_where (fixp->fx_file, fixp->fx_line,
2757 _("Value %ld too large for 8-bit PC-relative branch."),
2758 value);
2759 break;
2760
2761 case BFD_RELOC_M68HC11_3B:
2762 if (value <= 0 || value > 8)
2763 as_bad_where (fixp->fx_file, fixp->fx_line,
2764 _("Auto increment/decrement offset '%ld' is out of range."),
2765 value);
2766 if (where[0] & 0x8)
2767 value = 8 - value;
2768 else
2769 value--;
2770
2771 where[0] = where[0] | (value & 0x07);
2772 break;
2773
2774 default:
2775 as_fatal (_("Line %d: unknown relocation type: 0x%x."),
2776 fixp->fx_line, fixp->fx_r_type);
2777 }
82efde3a 2778
60bcf0fa
NC
2779 return 0;
2780}
2781
2782int
2783m68hc11_cleanup ()
2784{
2785 return 1;
2786}
This page took 0.144911 seconds and 4 git commands to generate.