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