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