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