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