* m68hc11-dis.c (PC_REGNUM): Define.
[deliverable/binutils-gdb.git] / gas / config / tc-m68hc11.c
CommitLineData
60bcf0fa 1/* tc-m68hc11.c -- Assembler code for the Motorola 68HC11 & 68HC12.
5a38dc70 2 Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
7bfda7eb 3 Written by Stephane Carrez (stcarrez@nerim.fr)
60bcf0fa
NC
4
5 This file is part of GAS, the GNU Assembler.
6
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
21
22#include <stdio.h>
60bcf0fa 23#include "as.h"
3882b010 24#include "safe-ctype.h"
60bcf0fa
NC
25#include "subsegs.h"
26#include "opcode/m68hc11.h"
27#include "dwarf2dbg.h"
7bfda7eb 28#include "elf/m68hc11.h"
60bcf0fa 29
60bcf0fa
NC
30const char comment_chars[] = ";!";
31const char line_comment_chars[] = "#*";
32const char line_separator_chars[] = "";
33
34const char EXP_CHARS[] = "eE";
35const char FLT_CHARS[] = "dD";
36
37#define STATE_CONDITIONAL_BRANCH (1)
38#define STATE_PC_RELATIVE (2)
39#define STATE_INDEXED_OFFSET (3)
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))
606ab118
AM
53#define RELAX_STATE(s) ((s) >> 2)
54#define RELAX_LENGTH(s) ((s) & 3)
60bcf0fa
NC
55
56#define IS_OPCODE(C1,C2) (((C1) & 0x0FF) == ((C2) & 0x0FF))
57
58/* This table describes how you change sizes for the various types of variable
59 size expressions. This version only supports two kinds. */
60
61/* The fields are:
fafb6d17
NC
62 How far Forward this mode will reach.
63 How far Backward this mode will reach.
64 How many bytes this mode will add to the size of the frag.
65 Which mode to go to if the offset won't fit in this one. */
66
098f2ec3 67relax_typeS md_relax_table[] = {
fafb6d17
NC
68 {1, 1, 0, 0}, /* First entries aren't used. */
69 {1, 1, 0, 0}, /* For no good reason except. */
70 {1, 1, 0, 0}, /* that the VAX doesn't either. */
60bcf0fa
NC
71 {1, 1, 0, 0},
72
73 /* Relax for bcc <L>.
74 These insns are translated into b!cc +3 jmp L. */
75 {(127), (-128), 0, ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_WORD)},
76 {0, 0, 3, 0},
77 {1, 1, 0, 0},
78 {1, 1, 0, 0},
79
80 /* Relax for bsr <L> and bra <L>.
81 These insns are translated into jsr and jmp. */
82 {(127), (-128), 0, ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD)},
83 {0, 0, 1, 0},
84 {1, 1, 0, 0},
85 {1, 1, 0, 0},
86
87 /* Relax for indexed offset: 5-bits, 9-bits, 16-bits. */
88 {(15), (-16), 0, ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9)},
89 {(255), (-256), 1, ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16)},
88051039 90 {0, 0, 2, 0},
60bcf0fa
NC
91 {1, 1, 0, 0},
92
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. */
098f2ec3 110typedef enum register_id {
60bcf0fa
NC
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
098f2ec3 122typedef struct operand {
60bcf0fa
NC
123 expressionS exp;
124 register_id reg1;
125 register_id reg2;
126 int mode;
127} operand;
128
098f2ec3 129struct m68hc11_opcode_def {
60bcf0fa
NC
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
138static struct m68hc11_opcode_def *m68hc11_opcode_defs = 0;
139static int m68hc11_nb_opcode_defs = 0;
140
098f2ec3 141typedef struct alias {
60bcf0fa
NC
142 const char *name;
143 const char *alias;
098f2ec3 144} alias;
60bcf0fa 145
098f2ec3 146static alias alias_opcodes[] = {
60bcf0fa
NC
147 {"cpd", "cmpd"},
148 {"cpx", "cmpx"},
149 {"cpy", "cmpy"},
150 {0, 0}
151};
152
fafb6d17
NC
153/* Local functions. */
154static register_id reg_name_search PARAMS ((char *));
155static register_id register_name PARAMS ((void));
27302d63
SC
156static int cmp_opcode PARAMS ((struct m68hc11_opcode *,
157 struct m68hc11_opcode *));
158static char *print_opcode_format PARAMS ((struct m68hc11_opcode *, int));
159static char *skip_whites PARAMS ((char *));
fafb6d17 160static int check_range PARAMS ((long, int));
60bcf0fa 161static void print_opcode_list PARAMS ((void));
60bcf0fa 162static void get_default_target PARAMS ((void));
fafb6d17
NC
163static void print_insn_format PARAMS ((char *));
164static int get_operand PARAMS ((operand *, int, long));
165static void fixup8 PARAMS ((expressionS *, int, int));
166static void fixup16 PARAMS ((expressionS *, int, int));
7bfda7eb 167static void fixup24 PARAMS ((expressionS *, int, int));
27302d63
SC
168static unsigned char convert_branch PARAMS ((unsigned char));
169static char *m68hc11_new_insn PARAMS ((int));
170static void build_dbranch_insn PARAMS ((struct m68hc11_opcode *,
171 operand *, int, int));
172static int build_indexed_byte PARAMS ((operand *, int, int));
173static int build_reg_mode PARAMS ((operand *, int));
174
175static struct m68hc11_opcode *find
176 PARAMS ((struct m68hc11_opcode_def *, operand *, int));
60bcf0fa 177static struct m68hc11_opcode *find_opcode
fafb6d17 178 PARAMS ((struct m68hc11_opcode_def *, operand *, int *));
60bcf0fa 179static void build_jump_insn
fafb6d17
NC
180 PARAMS ((struct m68hc11_opcode *, operand *, int, int));
181static void build_insn
182 PARAMS ((struct m68hc11_opcode *, operand *, int));
27302d63 183static int relaxable_symbol PARAMS ((symbolS *));
60bcf0fa 184
e371935f
SC
185/* Pseudo op to indicate a relax group. */
186static void s_m68hc11_relax PARAMS((int));
187
eb086b59
SC
188/* Pseudo op to control the ELF flags. */
189static 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. */
195static void s_m68hc11_mark_symbol PARAMS ((int));
196
60bcf0fa
NC
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
fafb6d17 205
60bcf0fa
NC
206 Setting the flag forbidds this. */
207static short flag_fixed_branchs = 0;
208
209/* Force to use long jumps (absolute) instead of relative branches. */
210static 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". */
216static short flag_strict_direct_addressing = 1;
217
218/* When an opcode has invalid operand, print out the syntax of the opcode
219 to stderr. */
220static 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. */
225static short flag_print_opcodes = 0;
226
227/* Opcode hash table. */
228static 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. */
233static int current_architecture = 0;
234
235/* Default cpu determined by 'get_default_target'. */
236static const char *default_cpu;
237
238/* Number of opcodes in the sorted table (filtered by current cpu). */
239static int num_opcodes;
240
241/* The opcodes sorted by name and filtered by current cpu. */
242static struct m68hc11_opcode *m68hc11_sorted_opcodes;
243
eb086b59
SC
244/* ELF flags to set in the output file header. */
245static int elf_flags = 0;
246
60bcf0fa
NC
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. */
098f2ec3 256const pseudo_typeS md_pseudo_table[] = {
60bcf0fa
NC
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},
986c6f4b
SC
262
263 /* Dwarf2 support for Gcc. */
9f1838ed 264 {"file", (void (*) PARAMS ((int))) dwarf2_directive_file, 0},
60bcf0fa
NC
265 {"loc", dwarf2_directive_loc, 0},
266
e629c13f
SC
267 /* Motorola ALIS. */
268 {"xrefb", s_ignore, 0}, /* Same as xref */
269
e371935f
SC
270 /* Gcc driven relaxation. */
271 {"relax", s_m68hc11_relax, 0},
272
eb086b59
SC
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
60bcf0fa
NC
282 {0, 0, 0}
283};
60bcf0fa
NC
284\f
285/* Options and initialization. */
286
5a38dc70 287const char *md_shortopts = "Sm:";
60bcf0fa 288
098f2ec3 289struct option md_longopts[] = {
60bcf0fa
NC
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};
310size_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. */
315const char *
316m68hc11_arch_format ()
317{
318 get_default_target ();
319 if (current_architecture & cpu6811)
320 return "elf32-m68hc11";
321 else
322 return "elf32-m68hc12";
323}
324
325enum bfd_architecture
326m68hc11_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
335int
336m68hc11_mach ()
337{
338 return 0;
339}
340
986c6f4b
SC
341/* Listing header selected according to cpu. */
342const char *
343m68hc11_listing_header ()
344{
345 if (current_architecture & cpu6811)
346 return "M68HC11 GAS ";
347 else
348 return "M68HC12 GAS ";
349}
350
60bcf0fa
NC
351void
352md_show_usage (stream)
353 FILE *stream;
354{
355 get_default_target ();
356 fprintf (stream, _("\
357Motorola 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. */
372static void
373get_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
402void
403m68hc11_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
426int
427md_parse_option (c, arg)
428 int c;
429 char *arg;
430{
431 get_default_target ();
432 switch (c)
433 {
986c6f4b 434 /* -S means keep external to 2 bit offset rather than 16 bit one. */
60bcf0fa
NC
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
476symbolS *
477md_undefined_symbol (name)
478 char *name ATTRIBUTE_UNUSED;
479{
480 return 0;
481}
482
fafb6d17 483/* Equal to MAX_PRECISION in atof-ieee.c. */
60bcf0fa
NC
484#define MAX_LITTLENUMS 6
485
486/* Turn a string in input_line_pointer into a floating point constant
bc0d738a
NC
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
60bcf0fa 489 returned, or NULL on OK. */
60bcf0fa
NC
490char *
491md_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
544valueT
545md_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
60bcf0fa
NC
553static int
554cmp_opcode (op1, op2)
555 struct m68hc11_opcode *op1;
556 struct m68hc11_opcode *op2;
557{
558 return strcmp (op1->name, op2->name);
559}
560
7bfda7eb
SC
561#define IS_CALL_SYMBOL(MODE) \
562(((MODE) & (M6812_OP_PAGE|M6811_OP_IND16)) \
563 == ((M6812_OP_PAGE|M6811_OP_IND16)))
564
60bcf0fa
NC
565/* Initialize the assembler. Create the opcode hash table
566 (sorted on the names) with the M6811 opcode table
567 (from opcode library). */
568void
569md_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++;
7bfda7eb
SC
649 /* Special case for call instruction. */
650 if ((opcodes->format & M6812_OP_PAGE)
651 && !(opcodes->format & M6811_OP_IND16))
652 expect++;
60bcf0fa
NC
653
654 if (expect < opc->min_operands)
655 opc->min_operands = expect;
7bfda7eb
SC
656 if (IS_CALL_SYMBOL (opcodes->format))
657 expect++;
60bcf0fa
NC
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
671void
672m68hc11_init_after_args ()
673{
674}
60bcf0fa
NC
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. */
681static char *
682print_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
7bfda7eb
SC
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
60bcf0fa
NC
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. */
801static void
802print_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)
fafb6d17
NC
810 printf (_("# Example of `%s' instructions\n\t.sect .text\n_start:\n"),
811 default_cpu);
60bcf0fa
NC
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
60bcf0fa
NC
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. */
847static void
848print_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
27302d63 868 fmt = print_opcode_format (opcode, 0);
60bcf0fa
NC
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}
60bcf0fa
NC
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. */
881static register_id
882reg_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
905static char *
906skip_whites (p)
907 char *p;
908{
909 while (*p == ' ' || *p == '\t')
910 p++;
911
912 return p;
913}
914
fafb6d17 915/* Check the string at input_line_pointer
60bcf0fa
NC
916 to see if it is a valid register name. */
917static register_id
918register_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
fafb6d17 933 /* Look to see if it's in the register table. */
60bcf0fa
NC
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
fafb6d17 949/* Parse a string of operands and return an array of expressions.
60bcf0fa 950
7bfda7eb
SC
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 */
60bcf0fa
NC
964static int
965get_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."),
fafb6d17 997 which);
60bcf0fa
NC
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++;
7bfda7eb 1025 mode = M6812_OP_D_IDX;
60bcf0fa
NC
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
7bfda7eb 1047 if (mode == M6811_OP_NONE || mode == M6812_OP_D_IDX)
60bcf0fa
NC
1048 reg = register_name ();
1049 else
1050 reg = REG_NONE;
1051
1052 if (reg != REG_NONE)
1053 {
1054 p = skip_whites (input_line_pointer);
7bfda7eb 1055 if (*p == ']' && mode == M6812_OP_D_IDX)
60bcf0fa
NC
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 {
7bfda7eb 1066 if (mode == M6812_OP_D_IDX)
60bcf0fa
NC
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);
7bfda7eb 1080 if (mode == M6812_OP_D_IDX)
60bcf0fa
NC
1081 {
1082 if (*p != ']')
1083 {
1084 as_bad (_("Missing `]' to close indexed-indirect mode."));
1085 return -1;
1086 }
1087 p++;
7bfda7eb 1088 oper->mode = M6812_OP_D_IDX;
60bcf0fa
NC
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
7bfda7eb 1141 || mode == M6812_OP_D_IDX)
60bcf0fa
NC
1142 {
1143 p = skip_whites (input_line_pointer);
1144
1145 if (*p == ',')
1146 {
098f2ec3
KH
1147 int possible_mode = M6811_OP_NONE;
1148 char *old_input_line;
7bfda7eb
SC
1149
1150 old_input_line = p;
60bcf0fa
NC
1151 p++;
1152
1153 /* 68HC12 pre increment or decrement. */
1154 if (mode == M6811_OP_NONE)
1155 {
1156 if (*p == '-')
1157 {
ae3e85dd 1158 possible_mode = M6812_PRE_DEC;
60bcf0fa 1159 p++;
60bcf0fa
NC
1160 }
1161 else if (*p == '+')
1162 {
ae3e85dd 1163 possible_mode = M6812_PRE_INC;
60bcf0fa 1164 p++;
60bcf0fa
NC
1165 }
1166 p = skip_whites (p);
1167 }
1168 input_line_pointer = p;
1169 reg = register_name ();
1170
098f2ec3
KH
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"));
fafb6d17 1188 /* Backtrack. */
60bcf0fa
NC
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 }
7bfda7eb 1203 if (mode == M6812_OP_D_IDX)
60bcf0fa
NC
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;
7bfda7eb
SC
1212 oper->reg1 = reg;
1213 oper->mode = M6812_OP_D_IDX_2;
1214 return 1;
60bcf0fa
NC
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 }
7bfda7eb 1249 input_line_pointer = old_input_line;
60bcf0fa
NC
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)
fafb6d17 1262 mode = M6811_OP_IND16 | M6811_OP_JUMP_REL;
60bcf0fa
NC
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. */
1277static int
1278check_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)
fafb6d17 1284 return (num != 0 && num <= 8 && num >= -8);
60bcf0fa 1285
986c6f4b 1286 /* The 68HC12 supports 5, 9 and 16-bit offsets. */
60bcf0fa 1287 if (mode & (M6812_INDEXED_IND | M6812_INDEXED | M6812_OP_IDX))
fafb6d17 1288 mode = M6811_OP_IND16;
60bcf0fa
NC
1289
1290 if (mode & M6812_OP_JUMP_REL16)
1291 mode = M6811_OP_IND16;
1292
7bfda7eb 1293 mode &= ~M6811_OP_BRANCH;
60bcf0fa
NC
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:
7bfda7eb 1303 case M6812_OP_PAGE:
60bcf0fa
NC
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:
7bfda7eb 1311 case M6811_OP_IND16 | M6812_OP_PAGE:
60bcf0fa
NC
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}
60bcf0fa
NC
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. */
1334static void
1335fixup8 (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,
b34976b6 1376 oper, TRUE, BFD_RELOC_8_PCREL);
60bcf0fa
NC
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,
b34976b6 1384 oper, FALSE,
60bcf0fa
NC
1385 ((opmode & M6811_OP_HIGH_ADDR)
1386 ? BFD_RELOC_M68HC11_HI8
1387 : ((opmode & M6811_OP_LOW_ADDR)
7bfda7eb
SC
1388 ? BFD_RELOC_M68HC11_LO8
1389 : ((mode & M6812_OP_PAGE)
1390 ? BFD_RELOC_M68HC11_PAGE : BFD_RELOC_8))));
60bcf0fa
NC
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
986c6f4b 1400/* Put a 2 byte expression described by 'oper'. If this expression contains
60bcf0fa
NC
1401 unresolved symbols, generate a 16-bit fixup. */
1402static void
1403fixup16 (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'."),
fafb6d17 1417 oper->X_add_number);
60bcf0fa
NC
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,
b34976b6 1428 (mode & M6812_OP_JUMP_REL16 ? TRUE : FALSE),
60bcf0fa 1429 (mode & M6812_OP_JUMP_REL16
7bfda7eb
SC
1430 ? BFD_RELOC_16_PCREL
1431 : (mode & M6812_OP_PAGE)
1432 ? BFD_RELOC_M68HC11_LO16 : BFD_RELOC_16));
60bcf0fa
NC
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}
7bfda7eb
SC
1442
1443/* Put a 3 byte expression described by 'oper'. If this expression contains
1444 unresolved symbols, generate a 24-bit fixup. */
1445static void
1446fixup24 (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,
b34976b6 1470 oper, FALSE, BFD_RELOC_M68HC11_24);
7bfda7eb
SC
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}
60bcf0fa
NC
1478\f
1479/* 68HC11 and 68HC12 code generation. */
1480
1481/* Translate the short branch/bsr instruction into a long branch. */
1482static unsigned char
1483convert_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. */
fafb6d17 1501static char *
60bcf0fa
NC
1502m68hc11_new_insn (size)
1503 int size;
1504{
fafb6d17 1505 char *f;
60bcf0fa
NC
1506
1507 f = frag_more (size);
1508
4dc7ead9 1509 dwarf2_emit_insn (size);
fafb6d17 1510
60bcf0fa
NC
1511 return f;
1512}
1513
1514/* Builds a jump instruction (bra, bcc, bsr). */
1515static void
1516build_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;
60bcf0fa
NC
1523 char *f;
1524 unsigned long n;
e371935f
SC
1525 fragS *frag;
1526 int where;
60bcf0fa
NC
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;
60bcf0fa
NC
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 {
e371935f
SC
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
60bcf0fa
NC
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 {
e371935f
SC
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
60bcf0fa
NC
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
e371935f
SC
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
60bcf0fa
NC
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 {
4fe7ef96
SC
1639 /* Allocate worst case storage. */
1640 opcode = m68hc11_new_insn (3);
60bcf0fa
NC
1641 number_to_chars_bigendian (opcode, code, 1);
1642 number_to_chars_bigendian (opcode + 1, 0, 1);
4fe7ef96
SC
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);
60bcf0fa
NC
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. */
1670static void
1671build_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;
60bcf0fa
NC
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;
60bcf0fa
NC
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. */
1765static int
1766build_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'."),
fafb6d17 1789 val);
60bcf0fa
NC
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
7bfda7eb 1823 if (mode & (M6812_OP_IDX | M6812_OP_D_IDX_2))
60bcf0fa
NC
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 {
ae3e85dd 1856 as_bad (_("Offset out of 5-bit range for movw/movb insn: %ld."),
098f2ec3 1857 val);
60bcf0fa
NC
1858 return -1;
1859 }
1860
7bfda7eb 1861 if (val >= -16 && val <= 15 && !(mode & M6812_OP_D_IDX_2))
60bcf0fa
NC
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 }
7bfda7eb 1869 else if (val >= -256 && val <= 255 && !(mode & M6812_OP_D_IDX_2))
60bcf0fa
NC
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;
7bfda7eb 1883 if (mode & M6812_OP_D_IDX_2)
60bcf0fa
NC
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 }
7bfda7eb
SC
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)
098f2ec3
KH
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,
b34976b6 1910 &op->exp, FALSE, BFD_RELOC_16);
098f2ec3
KH
1911 number_to_chars_bigendian (f, 0, 2);
1912 }
88051039 1913 else
098f2ec3
KH
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 }
60bcf0fa
NC
1922 return 3;
1923 }
1924
7bfda7eb 1925 if (mode & (M6812_OP_REG | M6812_OP_D_IDX))
60bcf0fa 1926 {
7bfda7eb 1927 if (mode & M6812_OP_D_IDX)
60bcf0fa
NC
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. */
1987static int
1988build_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). */
2021static void
2022build_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;
60bcf0fa
NC
2029 long format;
2030 int move_insn = 0;
e371935f
SC
2031 fragS *frag;
2032 int where;
60bcf0fa
NC
2033
2034 /* Put the page code instruction if there is one. */
2035 format = opcode->format;
e371935f
SC
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
60bcf0fa
NC
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++;
60bcf0fa
NC
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 {
986c6f4b 2073 build_indexed_byte (&operands[0], format, 1);
60bcf0fa
NC
2074 i = 1;
2075 format &= ~M6812_OP_IDX;
2076 }
2077 if (format & M6812_OP_IDX_P2)
2078 {
986c6f4b 2079 build_indexed_byte (&operands[1], format, 1);
60bcf0fa
NC
2080 i = 0;
2081 format &= ~M6812_OP_IDX_P2;
2082 }
2083 }
2084
2085 if (format & (M6811_OP_DIRECT | M6811_OP_IMM8))
2086 {
60bcf0fa
NC
2087 fixup8 (&operands[i].exp,
2088 format & (M6811_OP_DIRECT | M6811_OP_IMM8 | M6812_OP_TRAP_ID),
2089 operands[i].mode);
2090 i++;
2091 }
7bfda7eb
SC
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 }
60bcf0fa
NC
2099 else if (format & (M6811_OP_IMM16 | M6811_OP_IND16))
2100 {
7bfda7eb
SC
2101 fixup16 (&operands[i].exp,
2102 format & (M6811_OP_IMM16 | M6811_OP_IND16 | M6812_OP_PAGE),
60bcf0fa
NC
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
60bcf0fa
NC
2113 fixup8 (&operands[0].exp, M6811_OP_IX, operands[0].mode);
2114 i = 1;
2115 }
2116 else if (format &
7bfda7eb
SC
2117 (M6812_OP_IDX | M6812_OP_IDX_2 | M6812_OP_IDX_1
2118 | M6812_OP_D_IDX | M6812_OP_D_IDX_2))
60bcf0fa 2119 {
986c6f4b 2120 build_indexed_byte (&operands[i], format, move_insn);
60bcf0fa
NC
2121 i++;
2122 }
2123 else if (format & M6812_OP_REG && current_architecture & cpu6812)
2124 {
986c6f4b 2125 build_reg_mode (&operands[i], format);
60bcf0fa
NC
2126 i++;
2127 }
2128 if (format & M6811_OP_BITMASK)
2129 {
60bcf0fa
NC
2130 fixup8 (&operands[i].exp, M6811_OP_BITMASK, operands[i].mode);
2131 i++;
2132 }
2133 if (format & M6811_OP_JUMP_REL)
2134 {
60bcf0fa 2135 fixup8 (&operands[i].exp, M6811_OP_JUMP_REL, operands[i].mode);
60bcf0fa
NC
2136 }
2137 else if (format & M6812_OP_IND16_P2)
2138 {
60bcf0fa
NC
2139 fixup16 (&operands[1].exp, M6811_OP_IND16, operands[1].mode);
2140 }
7bfda7eb
SC
2141 if (format & M6812_OP_PAGE)
2142 {
2143 fixup8 (&operands[i].exp, M6812_OP_PAGE, operands[i].mode);
2144 }
60bcf0fa 2145}
60bcf0fa
NC
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. */
2152static struct m68hc11_opcode *
2153find (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++;
7bfda7eb
SC
2183 if ((opcode->format & M6812_OP_PAGE)
2184 && (!IS_CALL_SYMBOL (opcode->format) || nb_operands == 2))
2185 expect++;
60bcf0fa
NC
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;
7bfda7eb
SC
2218 if (i != 0 && (format & M6812_OP_PAGE) != 0)
2219 continue;
60bcf0fa
NC
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 {
df86943d
NC
2232 if (i == 0
2233 && (format & M6812_OP_REG)
2234 && (operands[i].reg2 == REG_NONE))
60bcf0fa 2235 continue;
df86943d
NC
2236 if (i == 0
2237 && (format & M6812_OP_REG)
2238 && (format & M6812_OP_REG_2)
2239 && (operands[i].reg2 != REG_NONE))
60bcf0fa 2240 continue;
df86943d
NC
2241 if (i == 0
2242 && (format & M6812_OP_IDX)
2243 && (operands[i].reg2 != REG_NONE))
2244 continue;
df86943d
NC
2245 if (i == 0
2246 && (format & M6812_OP_IDX)
60bcf0fa
NC
2247 && (format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2)))
2248 continue;
df86943d
NC
2249 if (i == 1
2250 && (format & M6812_OP_IDX_P2))
60bcf0fa
NC
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 }
7bfda7eb
SC
2270 if (mode & format & (M6812_OP_D_IDX | M6812_OP_D_IDX_2))
2271 {
2272 if (i == 0)
2273 continue;
2274 }
60bcf0fa
NC
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
60bcf0fa
NC
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. */
2325static struct m68hc11_opcode *
2326find_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)
fafb6d17 2346 return 0;
60bcf0fa
NC
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);
7bfda7eb
SC
2362 if (opcode && !(opcode->format & M6812_OP_PAGE))
2363 return opcode;
2364
2365 if (opcode && *input_line_pointer != ',')
fafb6d17 2366 return opcode;
60bcf0fa
NC
2367 }
2368
2369 if (*input_line_pointer == ',')
2370 input_line_pointer++;
2371 }
82efde3a 2372
60bcf0fa
NC
2373 return 0;
2374}
2375
2376#define M6812_XBCC_MARKER (M6812_OP_TBCC_MARKER \
2377 | M6812_OP_DBCC_MARKER \
2378 | M6812_OP_IBCC_MARKER)
60bcf0fa
NC
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. */
2385void
2386md_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
fafb6d17 2401 /* Drop leading whitespace. */
60bcf0fa
NC
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 {
3882b010 2411 name[nlen] = TOLOWER (op_start[nlen]);
60bcf0fa
NC
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'
3882b010 2453 || !ISALNUM (op_end[1])))
60bcf0fa
NC
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 {
3882b010 2460 name[nlen++] = TOLOWER (*op_end++);
60bcf0fa
NC
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
986c6f4b 2469 68HC12 to emulate a few 68HC11 instructions. */
60bcf0fa
NC
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);
fafb6d17 2513
60bcf0fa
NC
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))
27302d63 2536 build_dbranch_insn (opcode, operands, nb_operands, branch_optimize);
60bcf0fa
NC
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}
eb086b59
SC
2548
2549\f
2550/* Pseudo op to control the ELF flags. */
2551static void
2552s_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. */
2590static void
2591s_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}
e371935f
SC
2631
2632static void
2633s_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
60bcf0fa
NC
2653\f
2654/* Relocation, relaxation and frag conversions. */
e371935f
SC
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. */
60bcf0fa 2659long
e371935f
SC
2660md_pcrel_from (fixP)
2661 fixS *fixP;
60bcf0fa 2662{
e371935f 2663 if (fixP->fx_r_type == BFD_RELOC_M68HC11_RL_JUMP)
60bcf0fa
NC
2664 return 0;
2665
e371935f 2666 return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
60bcf0fa
NC
2667}
2668
2669/* If while processing a fixup, a reloc really needs to be created
2670 then it is done here. */
2671arelent *
2672tc_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
a161fe53
AM
2694 /* Since we use Rel instead of Rela, encode the vtable entry to be
2695 used in the relocation's section offset. */
2696 if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
2697 reloc->address = fixp->fx_offset;
2698
2699 reloc->addend = 0;
60bcf0fa
NC
2700 return reloc;
2701}
2702
2703void
2704md_convert_frag (abfd, sec, fragP)
2705 bfd *abfd ATTRIBUTE_UNUSED;
2706 asection *sec ATTRIBUTE_UNUSED;
2707 fragS *fragP;
2708{
2709 fixS *fixp;
88051039 2710 long value;
60bcf0fa
NC
2711 long disp;
2712 char *buffer_address = fragP->fr_literal;
2713
2714 /* Address in object code of the displacement. */
2715 register int object_address = fragP->fr_fix + fragP->fr_address;
2716
2717 buffer_address += fragP->fr_fix;
2718
2719 /* The displacement of the address, from current location. */
ac62c346 2720 value = S_GET_VALUE (fragP->fr_symbol);
88051039 2721 disp = (value + fragP->fr_offset) - object_address;
60bcf0fa
NC
2722
2723 switch (fragP->fr_subtype)
2724 {
2725 case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE):
2726 fragP->fr_opcode[1] = disp;
2727 break;
2728
2729 case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD):
2730 /* This relax is only for bsr and bra. */
2731 assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
2732 || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
2733 || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
2734
2735 fragP->fr_opcode[0] = convert_branch (fragP->fr_opcode[0]);
2736
2737 fix_new (fragP, fragP->fr_fix - 1, 2,
2738 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
2739 fragP->fr_fix += 1;
2740 break;
2741
2742 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_BYTE):
2743 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_BYTE):
2744 fragP->fr_opcode[1] = disp;
2745 break;
2746
2747 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_WORD):
2748 /* Invert branch. */
2749 fragP->fr_opcode[0] ^= 1;
fafb6d17 2750 fragP->fr_opcode[1] = 3; /* Branch offset. */
60bcf0fa
NC
2751 buffer_address[0] = M6811_JMP;
2752 fix_new (fragP, fragP->fr_fix + 1, 2,
2753 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
2754 fragP->fr_fix += 3;
2755 break;
2756
2757 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_WORD):
2758 /* Translate branch into a long branch. */
2759 fragP->fr_opcode[1] = fragP->fr_opcode[0];
2760 fragP->fr_opcode[0] = M6811_OPCODE_PAGE2;
2761
2762 fixp = fix_new (fragP, fragP->fr_fix, 2,
2763 fragP->fr_symbol, fragP->fr_offset, 1,
2764 BFD_RELOC_16_PCREL);
2765 fixp->fx_pcrel_adjust = 2;
2766 fragP->fr_fix += 2;
2767 break;
2768
2769 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS5):
88051039
SC
2770 fragP->fr_opcode[0] = fragP->fr_opcode[0] << 6;
2771 if ((fragP->fr_opcode[0] & 0x0ff) == 0x0c0)
098f2ec3 2772 fragP->fr_opcode[0] |= disp & 0x1f;
88051039 2773 else
098f2ec3 2774 fragP->fr_opcode[0] |= value & 0x1f;
60bcf0fa
NC
2775 break;
2776
2777 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9):
2778 fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3);
2779 fragP->fr_opcode[0] |= 0xE0;
88051039 2780 fix_new (fragP, fragP->fr_fix, 1,
60bcf0fa
NC
2781 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_8);
2782 fragP->fr_fix += 1;
2783 break;
2784
2785 case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16):
2786 fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3);
88051039
SC
2787 fragP->fr_opcode[0] |= 0xe2;
2788 if ((fragP->fr_opcode[0] & 0x0ff) == 0x0fa)
098f2ec3
KH
2789 {
2790 fixp = fix_new (fragP, fragP->fr_fix, 2,
2791 fragP->fr_symbol, fragP->fr_offset,
2792 1, BFD_RELOC_16_PCREL);
2793 fixp->fx_pcrel_adjust = 2;
2794 }
88051039 2795 else
098f2ec3
KH
2796 {
2797 fix_new (fragP, fragP->fr_fix, 2,
2798 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
2799 }
88051039 2800 fragP->fr_fix += 2;
60bcf0fa
NC
2801 break;
2802
2803 case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_BYTE):
2804 if (disp < 0)
2805 fragP->fr_opcode[0] |= 0x10;
2806
2807 fragP->fr_opcode[1] = disp & 0x0FF;
2808 break;
2809
2810 case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_WORD):
2811 /* Invert branch. */
2812 fragP->fr_opcode[0] ^= 0x20;
2813 fragP->fr_opcode[1] = 3; /* Branch offset. */
2814 buffer_address[0] = M6812_JMP;
2815 fix_new (fragP, fragP->fr_fix + 1, 2,
2816 fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
2817 fragP->fr_fix += 3;
2818 break;
2819
2820 default:
2821 break;
2822 }
2823}
2824
dbb8ad49
SC
2825/* On an ELF system, we can't relax a weak symbol. The weak symbol
2826 can be overridden at final link time by a non weak symbol. We can
2827 relax externally visible symbol because there is no shared library
2828 and such symbol can't be overridden (unless they are weak). */
d8273f3b
SC
2829static int
2830relaxable_symbol (symbol)
098f2ec3 2831 symbolS *symbol;
d8273f3b 2832{
dbb8ad49 2833 return ! S_IS_WEAK (symbol);
d8273f3b
SC
2834}
2835
60bcf0fa
NC
2836/* Force truly undefined symbols to their maximum size, and generally set up
2837 the frag list to be relaxed. */
2838int
2839md_estimate_size_before_relax (fragP, segment)
2840 fragS *fragP;
2841 asection *segment;
2842{
606ab118
AM
2843 if (RELAX_LENGTH (fragP->fr_subtype) == STATE_UNDF)
2844 {
2845 if (S_GET_SEGMENT (fragP->fr_symbol) != segment
2846 || !relaxable_symbol (fragP->fr_symbol))
2847 {
2848 /* Non-relaxable cases. */
2849 int old_fr_fix;
2850 char *buffer_address;
60bcf0fa 2851
606ab118
AM
2852 old_fr_fix = fragP->fr_fix;
2853 buffer_address = fragP->fr_fix + fragP->fr_literal;
60bcf0fa 2854
606ab118
AM
2855 switch (RELAX_STATE (fragP->fr_subtype))
2856 {
2857 case STATE_PC_RELATIVE:
2858
2859 /* This relax is only for bsr and bra. */
2860 assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
2861 || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
2862 || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
2863
2864 if (flag_fixed_branchs)
2865 as_bad_where (fragP->fr_file, fragP->fr_line,
2866 _("bra or bsr with undefined symbol."));
2867
2868 /* The symbol is undefined or in a separate section.
2869 Turn bra into a jmp and bsr into a jsr. The insn
2870 becomes 3 bytes long (instead of 2). A fixup is
2871 necessary for the unresolved symbol address. */
2872 fragP->fr_opcode[0] = convert_branch (fragP->fr_opcode[0]);
2873
13283e2d 2874 fix_new (fragP, fragP->fr_fix - 1, 2, fragP->fr_symbol,
606ab118 2875 fragP->fr_offset, 0, BFD_RELOC_16);
13283e2d 2876 fragP->fr_fix++;
606ab118 2877 break;
60bcf0fa 2878
606ab118
AM
2879 case STATE_CONDITIONAL_BRANCH:
2880 assert (current_architecture & cpu6811);
60bcf0fa 2881
606ab118
AM
2882 fragP->fr_opcode[0] ^= 1; /* Reverse sense of branch. */
2883 fragP->fr_opcode[1] = 3; /* Skip next jmp insn (3 bytes). */
60bcf0fa 2884
606ab118
AM
2885 /* Don't use fr_opcode[2] because this may be
2886 in a different frag. */
2887 buffer_address[0] = M6811_JMP;
60bcf0fa 2888
606ab118
AM
2889 fragP->fr_fix++;
2890 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
2891 fragP->fr_offset, 0, BFD_RELOC_16);
2892 fragP->fr_fix += 2;
2893 break;
60bcf0fa 2894
606ab118
AM
2895 case STATE_INDEXED_OFFSET:
2896 assert (current_architecture & cpu6812);
60bcf0fa 2897
606ab118
AM
2898 /* Switch the indexed operation to 16-bit mode. */
2899 fragP->fr_opcode[0] = fragP->fr_opcode[0] << 3;
2900 fragP->fr_opcode[0] |= 0xe2;
2901 fragP->fr_fix++;
2902 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
2903 fragP->fr_offset, 0, BFD_RELOC_16);
2904 fragP->fr_fix++;
2905 break;
60bcf0fa 2906
606ab118
AM
2907 case STATE_XBCC_BRANCH:
2908 assert (current_architecture & cpu6812);
2909
2910 fragP->fr_opcode[0] ^= 0x20; /* Reverse sense of branch. */
2911 fragP->fr_opcode[1] = 3; /* Skip next jmp insn (3 bytes). */
60bcf0fa 2912
606ab118
AM
2913 /* Don't use fr_opcode[2] because this may be
2914 in a different frag. */
2915 buffer_address[0] = M6812_JMP;
2916
2917 fragP->fr_fix++;
2918 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
2919 fragP->fr_offset, 0, BFD_RELOC_16);
2920 fragP->fr_fix += 2;
2921 break;
60bcf0fa 2922
606ab118
AM
2923 case STATE_CONDITIONAL_BRANCH_6812:
2924 assert (current_architecture & cpu6812);
2925
2926 /* Translate into a lbcc branch. */
2927 fragP->fr_opcode[1] = fragP->fr_opcode[0];
2928 fragP->fr_opcode[0] = M6811_OPCODE_PAGE2;
2929
2930 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
e371935f 2931 fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
606ab118
AM
2932 fragP->fr_fix += 2;
2933 break;
2934
2935 default:
2936 as_fatal (_("Subtype %d is not recognized."), fragP->fr_subtype);
2937 }
60bcf0fa 2938 frag_wane (fragP);
60bcf0fa 2939
606ab118
AM
2940 /* Return the growth in the fixed part of the frag. */
2941 return fragP->fr_fix - old_fr_fix;
2942 }
60bcf0fa 2943
606ab118
AM
2944 /* Relaxable cases. */
2945 switch (RELAX_STATE (fragP->fr_subtype))
60bcf0fa 2946 {
606ab118
AM
2947 case STATE_PC_RELATIVE:
2948 /* This relax is only for bsr and bra. */
2949 assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
2950 || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
2951 || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
2952
2953 fragP->fr_subtype = ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE);
2954 break;
2955
2956 case STATE_CONDITIONAL_BRANCH:
2957 assert (current_architecture & cpu6811);
2958
2959 fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH,
2960 STATE_BYTE);
2961 break;
2962
2963 case STATE_INDEXED_OFFSET:
2964 assert (current_architecture & cpu6812);
2965
60bcf0fa
NC
2966 fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_OFFSET,
2967 STATE_BITS5);
606ab118 2968 break;
60bcf0fa 2969
606ab118
AM
2970 case STATE_XBCC_BRANCH:
2971 assert (current_architecture & cpu6812);
60bcf0fa 2972
60bcf0fa 2973 fragP->fr_subtype = ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_BYTE);
606ab118 2974 break;
60bcf0fa 2975
606ab118
AM
2976 case STATE_CONDITIONAL_BRANCH_6812:
2977 assert (current_architecture & cpu6812);
60bcf0fa 2978
60bcf0fa
NC
2979 fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812,
2980 STATE_BYTE);
606ab118 2981 break;
60bcf0fa 2982 }
60bcf0fa
NC
2983 }
2984
606ab118
AM
2985 if (fragP->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))
2986 as_fatal (_("Subtype %d is not recognized."), fragP->fr_subtype);
2987
2988 /* Return the size of the variable part of the frag. */
2989 return md_relax_table[fragP->fr_subtype].rlx_length;
60bcf0fa
NC
2990}
2991
e371935f
SC
2992/* See whether we need to force a relocation into the output file. */
2993int
2994tc_m68hc11_force_relocation (fixP)
2995 fixS * fixP;
2996{
2997 switch (fixP->fx_r_type)
2998 {
2999 case BFD_RELOC_VTABLE_INHERIT:
3000 case BFD_RELOC_VTABLE_ENTRY:
3001 case BFD_RELOC_M68HC11_RL_GROUP:
3002 return 1;
3003
3004 default:
a161fe53 3005 break;
e371935f 3006 }
a161fe53
AM
3007
3008 return S_FORCE_RELOC (fixP->fx_addsy);
e371935f
SC
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. */
3016int
3017tc_m68hc11_fix_adjustable (fixP)
3018 fixS *fixP;
3019{
e371935f
SC
3020 switch (fixP->fx_r_type)
3021 {
3022 /* For the linker relaxation to work correctly, these relocs
3023 need to be on the symbol itself. */
3024 case BFD_RELOC_16:
3025 case BFD_RELOC_LO16:
3026 case BFD_RELOC_M68HC11_RL_JUMP:
3027 case BFD_RELOC_M68HC11_RL_GROUP:
3028 case BFD_RELOC_VTABLE_INHERIT:
3029 case BFD_RELOC_VTABLE_ENTRY:
3030 return 0;
3031
3032 case BFD_RELOC_32:
3033 default:
3034 return 1;
3035 }
3036}
3037
94f592af
NC
3038void
3039md_apply_fix3 (fixP, valP, seg)
3040 fixS *fixP;
3041 valueT *valP;
3042 segT seg ATTRIBUTE_UNUSED;
60bcf0fa
NC
3043{
3044 char *where;
94f592af 3045 long value = * valP;
60bcf0fa
NC
3046 int op_type;
3047
94f592af
NC
3048 if (fixP->fx_addsy == (symbolS *) NULL)
3049 fixP->fx_done = 1;
3050
a161fe53
AM
3051 /* We don't actually support subtracting a symbol. */
3052 if (fixP->fx_subsy != (symbolS *) NULL)
3053 as_bad_where (fixP->fx_file, fixP->fx_line, _("Expression too complex."));
60bcf0fa 3054
94f592af 3055 op_type = fixP->fx_r_type;
60bcf0fa
NC
3056
3057 /* Patch the instruction with the resolved operand. Elf relocation
3058 info will also be generated to take care of linker/loader fixups.
3059 The 68HC11 addresses only 64Kb, we are only concerned by 8 and 16-bit
3060 relocs. BFD_RELOC_8 is basically used for .page0 access (the linker
3061 will warn for overflows). BFD_RELOC_8_PCREL should not be generated
3062 because it's either resolved or turned out into non-relative insns (see
3063 relax table, bcc, bra, bsr transformations)
3064
3065 The BFD_RELOC_32 is necessary for the support of --gstabs. */
94f592af 3066 where = fixP->fx_frag->fr_literal + fixP->fx_where;
60bcf0fa 3067
94f592af 3068 switch (fixP->fx_r_type)
60bcf0fa
NC
3069 {
3070 case BFD_RELOC_32:
3071 bfd_putb32 ((bfd_vma) value, (unsigned char *) where);
3072 break;
3073
7bfda7eb
SC
3074 case BFD_RELOC_24:
3075 case BFD_RELOC_M68HC11_24:
3076 bfd_putb16 ((bfd_vma) (value & 0x0ffff), (unsigned char *) where);
3077 ((bfd_byte*) where)[2] = ((value >> 16) & 0x0ff);
3078 break;
3079
60bcf0fa
NC
3080 case BFD_RELOC_16:
3081 case BFD_RELOC_16_PCREL:
7bfda7eb 3082 case BFD_RELOC_M68HC11_LO16:
60bcf0fa
NC
3083 bfd_putb16 ((bfd_vma) value, (unsigned char *) where);
3084 if (value < -65537 || value > 65535)
94f592af 3085 as_bad_where (fixP->fx_file, fixP->fx_line,
60bcf0fa
NC
3086 _("Value out of 16-bit range."));
3087 break;
3088
3089 case BFD_RELOC_M68HC11_HI8:
3090 value = value >> 8;
fafb6d17 3091 /* Fall through. */
60bcf0fa
NC
3092
3093 case BFD_RELOC_M68HC11_LO8:
3094 case BFD_RELOC_8:
7bfda7eb 3095 case BFD_RELOC_M68HC11_PAGE:
fafb6d17
NC
3096#if 0
3097 bfd_putb8 ((bfd_vma) value, (unsigned char *) where);
3098#endif
60bcf0fa
NC
3099 ((bfd_byte *) where)[0] = (bfd_byte) value;
3100 break;
3101
3102 case BFD_RELOC_8_PCREL:
fafb6d17
NC
3103#if 0
3104 bfd_putb8 ((bfd_vma) value, (unsigned char *) where);
3105#endif
60bcf0fa
NC
3106 ((bfd_byte *) where)[0] = (bfd_byte) value;
3107
3108 if (value < -128 || value > 127)
94f592af 3109 as_bad_where (fixP->fx_file, fixP->fx_line,
60bcf0fa
NC
3110 _("Value %ld too large for 8-bit PC-relative branch."),
3111 value);
3112 break;
3113
3114 case BFD_RELOC_M68HC11_3B:
3115 if (value <= 0 || value > 8)
94f592af 3116 as_bad_where (fixP->fx_file, fixP->fx_line,
60bcf0fa
NC
3117 _("Auto increment/decrement offset '%ld' is out of range."),
3118 value);
3119 if (where[0] & 0x8)
3120 value = 8 - value;
3121 else
3122 value--;
3123
3124 where[0] = where[0] | (value & 0x07);
3125 break;
3126
e371935f
SC
3127 case BFD_RELOC_M68HC11_RL_JUMP:
3128 case BFD_RELOC_M68HC11_RL_GROUP:
3129 case BFD_RELOC_VTABLE_INHERIT:
3130 case BFD_RELOC_VTABLE_ENTRY:
3131 fixP->fx_done = 0;
3132 return;
3133
60bcf0fa
NC
3134 default:
3135 as_fatal (_("Line %d: unknown relocation type: 0x%x."),
94f592af 3136 fixP->fx_line, fixP->fx_r_type);
60bcf0fa 3137 }
60bcf0fa 3138}
eb086b59
SC
3139
3140/* Set the ELF specific flags. */
3141void
3142m68hc11_elf_final_processing ()
3143{
3144 elf_elfheader (stdoutput)->e_flags &= ~EF_M68HC11_ABI;
3145 elf_elfheader (stdoutput)->e_flags |= elf_flags;
3146}
This page took 0.348973 seconds and 4 git commands to generate.