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