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