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