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