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