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