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