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