OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.20.1/] [gas/] [config/] [tc-m68hc11.c] - Blame information for rev 205

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 205 julius
/* tc-m68hc11.c -- Assembler code for the Motorola 68HC11 & 68HC12.
2
   Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009
3
   Free Software Foundation, Inc.
4
   Written by Stephane Carrez (stcarrez@nerim.fr)
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
10
   the Free Software Foundation; either version 3, or (at your option)
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
20
   the Free Software Foundation, 51 Franklin Street - Fifth Floor,
21
   Boston, MA 02110-1301, USA.  */
22
 
23
#include "as.h"
24
#include "safe-ctype.h"
25
#include "subsegs.h"
26
#include "opcode/m68hc11.h"
27
#include "dwarf2dbg.h"
28
#include "elf/m68hc11.h"
29
 
30
const char comment_chars[] = ";!";
31
const char line_comment_chars[] = "#*";
32
const char line_separator_chars[] = "";
33
 
34
const char EXP_CHARS[] = "eE";
35
const char FLT_CHARS[] = "dD";
36
 
37
#define STATE_CONDITIONAL_BRANCH        (1)
38
#define STATE_PC_RELATIVE               (2)
39
#define STATE_INDEXED_OFFSET            (3)
40
#define STATE_INDEXED_PCREL             (4)
41
#define STATE_XBCC_BRANCH               (5)
42
#define STATE_CONDITIONAL_BRANCH_6812   (6)
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))
54
#define RELAX_STATE(s) ((s) >> 2)
55
#define RELAX_LENGTH(s) ((s) & 3)
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:
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
 
68
relax_typeS md_relax_table[] = {
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.  */
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)},
91
  {0, 0, 2, 0},
92
  {1, 1, 0, 0},
93
 
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
 
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.  */
119
typedef enum register_id {
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
 
131
typedef struct operand {
132
  expressionS exp;
133
  register_id reg1;
134
  register_id reg2;
135
  int mode;
136
} operand;
137
 
138
struct m68hc11_opcode_def {
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
 
147
static struct m68hc11_opcode_def *m68hc11_opcode_defs = 0;
148
static int m68hc11_nb_opcode_defs = 0;
149
 
150
typedef struct alias {
151
  const char *name;
152
  const char *alias;
153
} alias;
154
 
155
static alias alias_opcodes[] = {
156
  {"cpd", "cmpd"},
157
  {"cpx", "cmpx"},
158
  {"cpy", "cmpy"},
159
  {0, 0}
160
};
161
 
162
/* Local functions.  */
163
static register_id reg_name_search (char *);
164
static register_id register_name (void);
165
static int cmp_opcode (struct m68hc11_opcode *, struct m68hc11_opcode *);
166
static char *print_opcode_format (struct m68hc11_opcode *, int);
167
static char *skip_whites (char *);
168
static int check_range (long, int);
169
static void print_opcode_list (void);
170
static void get_default_target (void);
171
static void print_insn_format (char *);
172
static int get_operand (operand *, int, long);
173
static void fixup8 (expressionS *, int, int);
174
static void fixup16 (expressionS *, int, int);
175
static void fixup24 (expressionS *, int, int);
176
static unsigned char convert_branch (unsigned char);
177
static char *m68hc11_new_insn (int);
178
static void build_dbranch_insn (struct m68hc11_opcode *,
179
                                operand *, int, int);
180
static int build_indexed_byte (operand *, int, int);
181
static int build_reg_mode (operand *, int);
182
 
183
static struct m68hc11_opcode *find (struct m68hc11_opcode_def *,
184
                                    operand *, int);
185
static struct m68hc11_opcode *find_opcode (struct m68hc11_opcode_def *,
186
                                           operand *, int *);
187
static void build_jump_insn (struct m68hc11_opcode *, operand *, int, int);
188
static void build_insn (struct m68hc11_opcode *, operand *, int);
189
static int relaxable_symbol (symbolS *);
190
 
191
/* Pseudo op to indicate a relax group.  */
192
static void s_m68hc11_relax (int);
193
 
194
/* Pseudo op to control the ELF flags.  */
195
static void s_m68hc11_mode (int);
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.  */
201
static void s_m68hc11_mark_symbol (int);
202
 
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
211
 
212
  Setting the flag forbidds this.  */
213
static short flag_fixed_branches = 0;
214
 
215
/* Force to use long jumps (absolute) instead of relative branches.  */
216
static 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".  */
222
static short flag_strict_direct_addressing = 1;
223
 
224
/* When an opcode has invalid operand, print out the syntax of the opcode
225
   to stderr.  */
226
static 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.  */
231
static short flag_print_opcodes = 0;
232
 
233
/* Opcode hash table.  */
234
static struct hash_control *m68hc11_hash;
235
 
236
/* Current cpu (either cpu6811 or cpu6812).  This is determined automagically
237
   by 'get_default_target' by looking at default BFD vector.  This is overridden
238
   with the -m<cpu> option.  */
239
static int current_architecture = 0;
240
 
241
/* Default cpu determined by 'get_default_target'.  */
242
static const char *default_cpu;
243
 
244
/* Number of opcodes in the sorted table (filtered by current cpu).  */
245
static int num_opcodes;
246
 
247
/* The opcodes sorted by name and filtered by current cpu.  */
248
static struct m68hc11_opcode *m68hc11_sorted_opcodes;
249
 
250
/* ELF flags to set in the output file header.  */
251
static int elf_flags = E_M68HC11_F64;
252
 
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.  */
262
const pseudo_typeS md_pseudo_table[] = {
263
  /* The following pseudo-ops are supported for MRI compatibility.  */
264
  {"fcb", cons, 1},
265
  {"fdb", cons, 2},
266
  {"fcc", stringer, 8 + 1},
267
  {"rmb", s_space, 0},
268
 
269
  /* Motorola ALIS.  */
270
  {"xrefb", s_ignore, 0}, /* Same as xref  */
271
 
272
  /* Gcc driven relaxation.  */
273
  {"relax", s_m68hc11_relax, 0},
274
 
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
 
284
  {0, 0, 0}
285
};
286
 
287
/* Options and initialization.  */
288
 
289
const char *md_shortopts = "Sm:";
290
 
291
struct option md_longopts[] = {
292
#define OPTION_FORCE_LONG_BRANCH (OPTION_MD_BASE)
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.  */
295
 
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.  */
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
 
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
 
324
  {NULL, no_argument, NULL, 0}
325
};
326
size_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.  */
331
const char *
332
m68hc11_arch_format (void)
333
{
334
  get_default_target ();
335
  if (current_architecture & cpu6811)
336
    return "elf32-m68hc11";
337
  else
338
    return "elf32-m68hc12";
339
}
340
 
341
enum bfd_architecture
342
m68hc11_arch (void)
343
{
344
  get_default_target ();
345
  if (current_architecture & cpu6811)
346
    return bfd_arch_m68hc11;
347
  else
348
    return bfd_arch_m68hc12;
349
}
350
 
351
int
352
m68hc11_mach (void)
353
{
354
  return 0;
355
}
356
 
357
/* Listing header selected according to cpu.  */
358
const char *
359
m68hc11_listing_header (void)
360
{
361
  if (current_architecture & cpu6811)
362
    return "M68HC11 GAS ";
363
  else
364
    return "M68HC12 GAS ";
365
}
366
 
367
void
368
md_show_usage (FILE *stream)
369
{
370
  get_default_target ();
371
  fprintf (stream, _("\
372
Motorola 68HC11/68HC12/68HCS12 options:\n\
373
  -m68hc11 | -m68hc12 |\n\
374
  -m68hcs12               specify the processor [default %s]\n\
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\
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\
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.  */
392
static void
393
get_default_target (void)
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
 
422
void
423
m68hc11_print_statistics (FILE *file)
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
 
445
int
446
md_parse_option (int c, char *arg)
447
{
448
  get_default_target ();
449
  switch (c)
450
    {
451
      /* -S means keep external to 2 bit offset rather than 16 bit one.  */
452
    case OPTION_SHORT_BRANCHES:
453
    case 'S':
454
      flag_fixed_branches = 1;
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
 
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
 
493
    case 'm':
494
      if (strcasecmp (arg, "68hc11") == 0)
495
        current_architecture = cpu6811;
496
      else if (strcasecmp (arg, "68hc12") == 0)
497
        current_architecture = cpu6812;
498
      else if (strcasecmp (arg, "68hcs12") == 0)
499
        current_architecture = cpu6812 | cpu6812s;
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
 
511
symbolS *
512
md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
513
{
514
  return 0;
515
}
516
 
517
char *
518
md_atof (int type, char *litP, int *sizeP)
519
{
520
  return ieee_md_atof (type, litP, sizeP, TRUE);
521
}
522
 
523
valueT
524
md_section_align (asection *seg, valueT addr)
525
{
526
  int align = bfd_get_section_alignment (stdoutput, seg);
527
  return ((addr + (1 << align) - 1) & (-1 << align));
528
}
529
 
530
static int
531
cmp_opcode (struct m68hc11_opcode *op1, struct m68hc11_opcode *op2)
532
{
533
  return strcmp (op1->name, op2->name);
534
}
535
 
536
#define IS_CALL_SYMBOL(MODE) \
537
(((MODE) & (M6812_OP_PAGE|M6811_OP_IND16)) \
538
  == ((M6812_OP_PAGE|M6811_OP_IND16)))
539
 
540
/* Initialize the assembler.  Create the opcode hash table
541
   (sorted on the names) with the M6811 opcode table
542
   (from opcode library).  */
543
void
544
md_begin (void)
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
    }
584
  qsort (opcodes, num_opcodes, sizeof (struct m68hc11_opcode),
585
         (int (*) (const void*, const void*)) cmp_opcode);
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;
610
          hash_insert (m68hc11_hash, opcodes->name, opc);
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++;
625
      /* Special case for call instruction.  */
626
      if ((opcodes->format & M6812_OP_PAGE)
627
          && !(opcodes->format & M6811_OP_IND16))
628
        expect++;
629
 
630
      if (expect < opc->min_operands)
631
        opc->min_operands = expect;
632
      if (IS_CALL_SYMBOL (opcodes->format))
633
         expect++;
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
 
647
void
648
m68hc11_init_after_args (void)
649
{
650
}
651
 
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.  */
657
static char *
658
print_opcode_format (struct m68hc11_opcode *opcode, int example)
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
 
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
 
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.  */
775
static void
776
print_opcode_list (void)
777
{
778
  int i;
779
  char *prev_name = "";
780
  struct m68hc11_opcode *opcodes;
781
  int example = flag_print_opcodes == 2;
782
 
783
  if (example)
784
    printf (_("# Example of `%s' instructions\n\t.sect .text\n_start:\n"),
785
            default_cpu);
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
 
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.  */
821
static void
822
print_insn_format (char *name)
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
 
841
      fmt = print_opcode_format (opcode, 0);
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
}
849
 
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.  */
854
static register_id
855
reg_name_search (char *name)
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
 
877
static char *
878
skip_whites (char *p)
879
{
880
  while (*p == ' ' || *p == '\t')
881
    p++;
882
 
883
  return p;
884
}
885
 
886
/* Check the string at input_line_pointer
887
   to see if it is a valid register name.  */
888
static register_id
889
register_name (void)
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
 
904
  /* Look to see if it's in the register table.  */
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
}
919
#define M6811_OP_CALL_ADDR    0x00800000
920
#define M6811_OP_PAGE_ADDR    0x04000000
921
 
922
/* Parse a string of operands and return an array of expressions.
923
 
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  */
937
static int
938
get_operand (operand *oper, int which, long opmode)
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."),
967
                  which);
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
        }
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
        }
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++;
1013
      mode = M6812_OP_D_IDX;
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
    }
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
    }
1039
  input_line_pointer = p;
1040
 
1041
  if (mode == M6811_OP_NONE || mode == M6812_OP_D_IDX)
1042
    reg = register_name ();
1043
  else
1044
    reg = REG_NONE;
1045
 
1046
  if (reg != REG_NONE)
1047
    {
1048
      p = skip_whites (input_line_pointer);
1049
      if (*p == ']' && mode == M6812_OP_D_IDX)
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
        {
1060
          if (mode == M6812_OP_D_IDX)
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);
1074
          if (mode == M6812_OP_D_IDX)
1075
            {
1076
              if (*p != ']')
1077
                {
1078
                  as_bad (_("Missing `]' to close indexed-indirect mode."));
1079
                  return -1;
1080
                }
1081
              p++;
1082
              oper->mode = M6812_OP_D_IDX;
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
1135
      || mode == M6812_OP_D_IDX)
1136
    {
1137
      p = skip_whites (input_line_pointer);
1138
 
1139
      if (*p == ',')
1140
        {
1141
          int possible_mode = M6811_OP_NONE;
1142
          char *old_input_line;
1143
 
1144
          old_input_line = p;
1145
          p++;
1146
 
1147
          /* 68HC12 pre increment or decrement.  */
1148
          if (mode == M6811_OP_NONE)
1149
            {
1150
              if (*p == '-')
1151
                {
1152
                  possible_mode = M6812_PRE_DEC;
1153
                  p++;
1154
                }
1155
              else if (*p == '+')
1156
                {
1157
                  possible_mode = M6812_PRE_INC;
1158
                  p++;
1159
                }
1160
              p = skip_whites (p);
1161
            }
1162
          input_line_pointer = p;
1163
          reg = register_name ();
1164
 
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"));
1182
          /* Backtrack.  */
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
            }
1197
          if (mode == M6812_OP_D_IDX)
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;
1206
              oper->reg1 = reg;
1207
              oper->mode = M6812_OP_D_IDX_2;
1208
              return 1;
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
            }
1243
          input_line_pointer = old_input_line;
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)
1256
    mode = M6811_OP_IND16 | M6811_OP_JUMP_REL;
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.  */
1271
static int
1272
check_range (long num, int mode)
1273
{
1274
  /* Auto increment and decrement are ok for [-8..8] without 0.  */
1275
  if (mode & M6812_AUTO_INC_DEC)
1276
    return (num != 0 && num <= 8 && num >= -8);
1277
 
1278
  /* The 68HC12 supports 5, 9 and 16-bit offsets.  */
1279
  if (mode & (M6812_INDEXED_IND | M6812_INDEXED | M6812_OP_IDX))
1280
    mode = M6811_OP_IND16;
1281
 
1282
  if (mode & M6812_OP_JUMP_REL16)
1283
    mode = M6811_OP_IND16;
1284
 
1285
  mode &= ~M6811_OP_BRANCH;
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:
1295
    case M6812_OP_PAGE:
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:
1303
    case M6811_OP_IND16 | M6812_OP_PAGE:
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
}
1321
 
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.  */
1326
static void
1327
fixup8 (expressionS *oper, int mode, int opmode)
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,
1365
                              oper, TRUE, BFD_RELOC_8_PCREL);
1366
          fixp->fx_pcrel_adjust = 1;
1367
        }
1368
      else
1369
        {
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;
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
 
1397
/* Put a 2 byte expression described by 'oper'.  If this expression contains
1398
   unresolved symbols, generate a 16-bit fixup.  */
1399
static void
1400
fixup16 (expressionS *oper, int mode, int opmode ATTRIBUTE_UNUSED)
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'."),
1411
                  oper->X_add_number);
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;
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;
1428
 
1429
      /* Now create a 16-bit fixup.  */
1430
      fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 2,
1431
                          oper,
1432
                          reloc == BFD_RELOC_16_PCREL,
1433
                          reloc);
1434
      number_to_chars_bigendian (f, 0, 2);
1435
      if (reloc == BFD_RELOC_16_PCREL)
1436
        fixp->fx_pcrel_adjust = 2;
1437
      if (reloc == BFD_RELOC_M68HC11_LO16)
1438
        fixp->fx_no_overflow = 1;
1439
    }
1440
  else
1441
    {
1442
      as_fatal (_("Operand `%x' not recognized in fixup16."), oper->X_op);
1443
    }
1444
}
1445
 
1446
/* Put a 3 byte expression described by 'oper'.  If this expression contains
1447
   unresolved symbols, generate a 24-bit fixup.  */
1448
static void
1449
fixup24 (expressionS *oper, int mode, int opmode ATTRIBUTE_UNUSED)
1450
{
1451
  char *f;
1452
 
1453
  f = frag_more (3);
1454
 
1455
  if (oper->X_op == O_constant)
1456
    {
1457
      if (!check_range (oper->X_add_number, mode))
1458
        {
1459
          as_bad (_("Operand out of 16-bit range: `%ld'."),
1460
                  oper->X_add_number);
1461
        }
1462
      number_to_chars_bigendian (f, oper->X_add_number & 0x0FFFFFF, 3);
1463
    }
1464
  else if (oper->X_op != O_register)
1465
    {
1466
      fixS *fixp;
1467
 
1468
      /* Now create a 24-bit fixup.  */
1469
      fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 3,
1470
                          oper, FALSE, BFD_RELOC_M68HC11_24);
1471
      number_to_chars_bigendian (f, 0, 3);
1472
    }
1473
  else
1474
    {
1475
      as_fatal (_("Operand `%x' not recognized in fixup16."), oper->X_op);
1476
    }
1477
}
1478
 
1479
/* 68HC11 and 68HC12 code generation.  */
1480
 
1481
/* Translate the short branch/bsr instruction into a long branch.  */
1482
static unsigned char
1483
convert_branch (unsigned char code)
1484
{
1485
  if (IS_OPCODE (code, M6812_BSR))
1486
    return M6812_JSR;
1487
  else if (IS_OPCODE (code, M6811_BSR))
1488
    return M6811_JSR;
1489
  else if (IS_OPCODE (code, M6811_BRA))
1490
    return (current_architecture & cpu6812) ? M6812_JMP : M6811_JMP;
1491
  else
1492
    as_fatal (_("Unexpected branch conversion with `%x'"), code);
1493
 
1494
  /* Keep gcc happy.  */
1495
  return M6811_JSR;
1496
}
1497
 
1498
/* Start a new insn that contains at least 'size' bytes.  Record the
1499
   line information of that insn in the dwarf2 debug sections.  */
1500
static char *
1501
m68hc11_new_insn (int size)
1502
{
1503
  char *f;
1504
 
1505
  f = frag_more (size);
1506
 
1507
  dwarf2_emit_insn (size);
1508
 
1509
  return f;
1510
}
1511
 
1512
/* Builds a jump instruction (bra, bcc, bsr).  */
1513
static void
1514
build_jump_insn (struct m68hc11_opcode *opcode, operand operands[],
1515
                 int nb_operands, int jmp_mode)
1516
{
1517
  unsigned char code;
1518
  char *f;
1519
  unsigned long n;
1520
  fragS *frag;
1521
  int where;
1522
 
1523
  /* The relative branch conversion is not supported for
1524
     brclr and brset.  */
1525
  gas_assert ((opcode->format & M6811_OP_BITMASK) == 0);
1526
  gas_assert (nb_operands == 1);
1527
  gas_assert (operands[0].reg1 == REG_NONE && operands[0].reg2 == REG_NONE);
1528
 
1529
  code = opcode->opcode;
1530
 
1531
  n = operands[0].exp.X_add_number;
1532
 
1533
  /* Turn into a long branch:
1534
     - when force long branch option (and not for jbcc pseudos),
1535
     - when jbcc and the constant is out of -128..127 range,
1536
     - when branch optimization is allowed and branch out of range.  */
1537
  if ((jmp_mode == 0 && flag_force_long_jumps)
1538
      || (operands[0].exp.X_op == O_constant
1539
          && (!check_range (n, opcode->format) &&
1540
              (jmp_mode == 1 || flag_fixed_branches == 0))))
1541
    {
1542
      frag = frag_now;
1543
      where = frag_now_fix ();
1544
 
1545
      fix_new (frag_now, frag_now_fix (), 0,
1546
               &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
1547
 
1548
      if (code == M6811_BSR || code == M6811_BRA || code == M6812_BSR)
1549
        {
1550
          code = convert_branch (code);
1551
 
1552
          f = m68hc11_new_insn (1);
1553
          number_to_chars_bigendian (f, code, 1);
1554
        }
1555
      else if (current_architecture & cpu6812)
1556
        {
1557
          /* 68HC12: translate the bcc into a lbcc.  */
1558
          f = m68hc11_new_insn (2);
1559
          number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1);
1560
          number_to_chars_bigendian (f + 1, code, 1);
1561
          fixup16 (&operands[0].exp, M6812_OP_JUMP_REL16,
1562
                   M6812_OP_JUMP_REL16);
1563
          return;
1564
        }
1565
      else
1566
        {
1567
          /* 68HC11: translate the bcc into b!cc +3; jmp <L>.  */
1568
          f = m68hc11_new_insn (3);
1569
          code ^= 1;
1570
          number_to_chars_bigendian (f, code, 1);
1571
          number_to_chars_bigendian (f + 1, 3, 1);
1572
          number_to_chars_bigendian (f + 2, M6811_JMP, 1);
1573
        }
1574
      fixup16 (&operands[0].exp, M6811_OP_IND16, M6811_OP_IND16);
1575
      return;
1576
    }
1577
 
1578
  /* Branch with a constant that must fit in 8-bits.  */
1579
  if (operands[0].exp.X_op == O_constant)
1580
    {
1581
      if (!check_range (n, opcode->format))
1582
        {
1583
          as_bad (_("Operand out of range for a relative branch: `%ld'"),
1584
                  n);
1585
        }
1586
      else if (opcode->format & M6812_OP_JUMP_REL16)
1587
        {
1588
          f = m68hc11_new_insn (4);
1589
          number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1);
1590
          number_to_chars_bigendian (f + 1, code, 1);
1591
          number_to_chars_bigendian (f + 2, n & 0x0ffff, 2);
1592
        }
1593
      else
1594
        {
1595
          f = m68hc11_new_insn (2);
1596
          number_to_chars_bigendian (f, code, 1);
1597
          number_to_chars_bigendian (f + 1, n & 0x0FF, 1);
1598
        }
1599
    }
1600
  else if (opcode->format & M6812_OP_JUMP_REL16)
1601
    {
1602
      frag = frag_now;
1603
      where = frag_now_fix ();
1604
 
1605
      fix_new (frag_now, frag_now_fix (), 0,
1606
               &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
1607
 
1608
      f = m68hc11_new_insn (2);
1609
      number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1);
1610
      number_to_chars_bigendian (f + 1, code, 1);
1611
      fixup16 (&operands[0].exp, M6812_OP_JUMP_REL16, M6812_OP_JUMP_REL16);
1612
    }
1613
  else
1614
    {
1615
      char *opcode;
1616
 
1617
      frag = frag_now;
1618
      where = frag_now_fix ();
1619
 
1620
      fix_new (frag_now, frag_now_fix (), 0,
1621
               &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
1622
 
1623
      /* Branch offset must fit in 8-bits, don't do some relax.  */
1624
      if (jmp_mode == 0 && flag_fixed_branches)
1625
        {
1626
          opcode = m68hc11_new_insn (1);
1627
          number_to_chars_bigendian (opcode, code, 1);
1628
          fixup8 (&operands[0].exp, M6811_OP_JUMP_REL, M6811_OP_JUMP_REL);
1629
        }
1630
 
1631
      /* bra/bsr made be changed into jmp/jsr.  */
1632
      else if (code == M6811_BSR || code == M6811_BRA || code == M6812_BSR)
1633
        {
1634
          /* Allocate worst case storage.  */
1635
          opcode = m68hc11_new_insn (3);
1636
          number_to_chars_bigendian (opcode, code, 1);
1637
          number_to_chars_bigendian (opcode + 1, 0, 1);
1638
          frag_variant (rs_machine_dependent, 1, 1,
1639
                        ENCODE_RELAX (STATE_PC_RELATIVE, STATE_UNDF),
1640
                        operands[0].exp.X_add_symbol, (offsetT) n,
1641
                        opcode);
1642
        }
1643
      else if (current_architecture & cpu6812)
1644
        {
1645
          opcode = m68hc11_new_insn (2);
1646
          number_to_chars_bigendian (opcode, code, 1);
1647
          number_to_chars_bigendian (opcode + 1, 0, 1);
1648
          frag_var (rs_machine_dependent, 2, 2,
1649
                    ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_UNDF),
1650
                    operands[0].exp.X_add_symbol, (offsetT) n, opcode);
1651
        }
1652
      else
1653
        {
1654
          opcode = m68hc11_new_insn (2);
1655
          number_to_chars_bigendian (opcode, code, 1);
1656
          number_to_chars_bigendian (opcode + 1, 0, 1);
1657
          frag_var (rs_machine_dependent, 3, 3,
1658
                    ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_UNDF),
1659
                    operands[0].exp.X_add_symbol, (offsetT) n, opcode);
1660
        }
1661
    }
1662
}
1663
 
1664
/* Builds a dbne/dbeq/tbne/tbeq instruction.  */
1665
static void
1666
build_dbranch_insn (struct m68hc11_opcode *opcode, operand operands[],
1667
                    int nb_operands, int jmp_mode)
1668
{
1669
  unsigned char code;
1670
  char *f;
1671
  unsigned long n;
1672
 
1673
  /* The relative branch conversion is not supported for
1674
     brclr and brset.  */
1675
  gas_assert ((opcode->format & M6811_OP_BITMASK) == 0);
1676
  gas_assert (nb_operands == 2);
1677
  gas_assert (operands[0].reg1 != REG_NONE);
1678
 
1679
  code = opcode->opcode & 0x0FF;
1680
 
1681
  f = m68hc11_new_insn (1);
1682
  number_to_chars_bigendian (f, code, 1);
1683
 
1684
  n = operands[1].exp.X_add_number;
1685
  code = operands[0].reg1;
1686
 
1687
  if (operands[0].reg1 == REG_NONE || operands[0].reg1 == REG_CCR
1688
      || operands[0].reg1 == REG_PC)
1689
    as_bad (_("Invalid register for dbcc/tbcc instruction."));
1690
 
1691
  if (opcode->format & M6812_OP_IBCC_MARKER)
1692
    code |= 0x80;
1693
  else if (opcode->format & M6812_OP_TBCC_MARKER)
1694
    code |= 0x40;
1695
 
1696
  if (!(opcode->format & M6812_OP_EQ_MARKER))
1697
    code |= 0x20;
1698
 
1699
  /* Turn into a long branch:
1700
     - when force long branch option (and not for jbcc pseudos),
1701
     - when jdbcc and the constant is out of -256..255 range,
1702
     - when branch optimization is allowed and branch out of range.  */
1703
  if ((jmp_mode == 0 && flag_force_long_jumps)
1704
      || (operands[1].exp.X_op == O_constant
1705
          && (!check_range (n, M6812_OP_IBCC_MARKER) &&
1706
              (jmp_mode == 1 || flag_fixed_branches == 0))))
1707
    {
1708
      f = frag_more (2);
1709
      code ^= 0x20;
1710
      number_to_chars_bigendian (f, code, 1);
1711
      number_to_chars_bigendian (f + 1, M6812_JMP, 1);
1712
      fixup16 (&operands[0].exp, M6811_OP_IND16, M6811_OP_IND16);
1713
      return;
1714
    }
1715
 
1716
  /* Branch with a constant that must fit in 9-bits.  */
1717
  if (operands[1].exp.X_op == O_constant)
1718
    {
1719
      if (!check_range (n, M6812_OP_IBCC_MARKER))
1720
        {
1721
          as_bad (_("Operand out of range for a relative branch: `%ld'"),
1722
                  n);
1723
        }
1724
      else
1725
        {
1726
          if ((long) n < 0)
1727
            code |= 0x10;
1728
 
1729
          f = frag_more (2);
1730
          number_to_chars_bigendian (f, code, 1);
1731
          number_to_chars_bigendian (f + 1, n & 0x0FF, 1);
1732
        }
1733
    }
1734
  else
1735
    {
1736
      /* Branch offset must fit in 8-bits, don't do some relax.  */
1737
      if (jmp_mode == 0 && flag_fixed_branches)
1738
        {
1739
          fixup8 (&operands[0].exp, M6811_OP_JUMP_REL, M6811_OP_JUMP_REL);
1740
        }
1741
 
1742
      else
1743
        {
1744
          f = frag_more (2);
1745
          number_to_chars_bigendian (f, code, 1);
1746
          number_to_chars_bigendian (f + 1, 0, 1);
1747
          frag_var (rs_machine_dependent, 3, 3,
1748
                    ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_UNDF),
1749
                    operands[1].exp.X_add_symbol, (offsetT) n, f);
1750
        }
1751
    }
1752
}
1753
 
1754
#define OP_EXTENDED (M6811_OP_PAGE2 | M6811_OP_PAGE3 | M6811_OP_PAGE4)
1755
 
1756
/* Assemble the post index byte for 68HC12 extended addressing modes.  */
1757
static int
1758
build_indexed_byte (operand *op, int format ATTRIBUTE_UNUSED, int move_insn)
1759
{
1760
  unsigned char byte = 0;
1761
  char *f;
1762
  int mode;
1763
  long val;
1764
 
1765
  val = op->exp.X_add_number;
1766
  mode = op->mode;
1767
  if (mode & M6812_AUTO_INC_DEC)
1768
    {
1769
      byte = 0x20;
1770
      if (mode & (M6812_POST_INC | M6812_POST_DEC))
1771
        byte |= 0x10;
1772
 
1773
      if (op->exp.X_op == O_constant)
1774
        {
1775
          if (!check_range (val, mode))
1776
            {
1777
              as_bad (_("Increment/decrement value is out of range: `%ld'."),
1778
                      val);
1779
            }
1780
          if (mode & (M6812_POST_INC | M6812_PRE_INC))
1781
            byte |= (val - 1) & 0x07;
1782
          else
1783
            byte |= (8 - ((val) & 7)) | 0x8;
1784
        }
1785
      switch (op->reg1)
1786
        {
1787
        case REG_NONE:
1788
          as_fatal (_("Expecting a register."));
1789
 
1790
        case REG_X:
1791
          byte |= 0;
1792
          break;
1793
 
1794
        case REG_Y:
1795
          byte |= 0x40;
1796
          break;
1797
 
1798
        case REG_SP:
1799
          byte |= 0x80;
1800
          break;
1801
 
1802
        default:
1803
          as_bad (_("Invalid register for post/pre increment."));
1804
          break;
1805
        }
1806
 
1807
      f = frag_more (1);
1808
      number_to_chars_bigendian (f, byte, 1);
1809
      return 1;
1810
    }
1811
 
1812
  if (mode & (M6812_OP_IDX | M6812_OP_D_IDX_2))
1813
    {
1814
      switch (op->reg1)
1815
        {
1816
        case REG_X:
1817
          byte = 0;
1818
          break;
1819
 
1820
        case REG_Y:
1821
          byte = 1;
1822
          break;
1823
 
1824
        case REG_SP:
1825
          byte = 2;
1826
          break;
1827
 
1828
        case REG_PC:
1829
          byte = 3;
1830
          break;
1831
 
1832
        default:
1833
          as_bad (_("Invalid register."));
1834
          break;
1835
        }
1836
      if (op->exp.X_op == O_constant)
1837
        {
1838
          if (!check_range (val, M6812_OP_IDX))
1839
            {
1840
              as_bad (_("Offset out of 16-bit range: %ld."), val);
1841
            }
1842
 
1843
          if (move_insn && !(val >= -16 && val <= 15))
1844
            {
1845
              as_bad (_("Offset out of 5-bit range for movw/movb insn: %ld."),
1846
                      val);
1847
              return -1;
1848
            }
1849
 
1850
          if (val >= -16 && val <= 15 && !(mode & M6812_OP_D_IDX_2))
1851
            {
1852
              byte = byte << 6;
1853
              byte |= val & 0x1f;
1854
              f = frag_more (1);
1855
              number_to_chars_bigendian (f, byte, 1);
1856
              return 1;
1857
            }
1858
          else if (val >= -256 && val <= 255 && !(mode & M6812_OP_D_IDX_2))
1859
            {
1860
              byte = byte << 3;
1861
              byte |= 0xe0;
1862
              if (val < 0)
1863
                byte |= 0x1;
1864
              f = frag_more (2);
1865
              number_to_chars_bigendian (f, byte, 1);
1866
              number_to_chars_bigendian (f + 1, val & 0x0FF, 1);
1867
              return 2;
1868
            }
1869
          else
1870
            {
1871
              byte = byte << 3;
1872
              if (mode & M6812_OP_D_IDX_2)
1873
                byte |= 0xe3;
1874
              else
1875
                byte |= 0xe2;
1876
 
1877
              f = frag_more (3);
1878
              number_to_chars_bigendian (f, byte, 1);
1879
              number_to_chars_bigendian (f + 1, val & 0x0FFFF, 2);
1880
              return 3;
1881
            }
1882
        }
1883
      if (mode & M6812_OP_D_IDX_2)
1884
        {
1885
          byte = (byte << 3) | 0xe3;
1886
          f = frag_more (1);
1887
          number_to_chars_bigendian (f, byte, 1);
1888
 
1889
          fixup16 (&op->exp, 0, 0);
1890
        }
1891
      else if (op->reg1 != REG_PC)
1892
        {
1893
          symbolS *sym;
1894
          offsetT off;
1895
 
1896
          f = frag_more (1);
1897
          number_to_chars_bigendian (f, byte, 1);
1898
          sym = op->exp.X_add_symbol;
1899
          off = op->exp.X_add_number;
1900
          if (op->exp.X_op != O_symbol)
1901
            {
1902
              sym = make_expr_symbol (&op->exp);
1903
              off = 0;
1904
            }
1905
          /* movb/movw cannot be relaxed.  */
1906
          if (move_insn)
1907
            {
1908
              byte <<= 6;
1909
              number_to_chars_bigendian (f, byte, 1);
1910
              fix_new (frag_now, f - frag_now->fr_literal, 1,
1911
                       sym, off, 0, BFD_RELOC_M68HC12_5B);
1912
              return 1;
1913
            }
1914
          else
1915
            {
1916
              number_to_chars_bigendian (f, byte, 1);
1917
              frag_var (rs_machine_dependent, 2, 2,
1918
                        ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_UNDF),
1919
                        sym, off, f);
1920
            }
1921
        }
1922
      else
1923
        {
1924
          f = frag_more (1);
1925
          /* movb/movw cannot be relaxed.  */
1926
          if (move_insn)
1927
            {
1928
              byte <<= 6;
1929
              number_to_chars_bigendian (f, byte, 1);
1930
              fix_new (frag_now, f - frag_now->fr_literal, 1,
1931
                       op->exp.X_add_symbol, op->exp.X_add_number, 0, BFD_RELOC_M68HC12_5B);
1932
              return 1;
1933
            }
1934
          else
1935
            {
1936
              number_to_chars_bigendian (f, byte, 1);
1937
              frag_var (rs_machine_dependent, 2, 2,
1938
                        ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_UNDF),
1939
                        op->exp.X_add_symbol,
1940
                        op->exp.X_add_number, f);
1941
            }
1942
        }
1943
      return 3;
1944
    }
1945
 
1946
  if (mode & (M6812_OP_REG | M6812_OP_D_IDX))
1947
    {
1948
      if (mode & M6812_OP_D_IDX)
1949
        {
1950
          if (op->reg1 != REG_D)
1951
            as_bad (_("Expecting register D for indexed indirect mode."));
1952
          if (move_insn)
1953
            as_bad (_("Indexed indirect mode is not allowed for movb/movw."));
1954
 
1955
          byte = 0xE7;
1956
        }
1957
      else
1958
        {
1959
          switch (op->reg1)
1960
            {
1961
            case REG_A:
1962
              byte = 0xE4;
1963
              break;
1964
 
1965
            case REG_B:
1966
              byte = 0xE5;
1967
              break;
1968
 
1969
            default:
1970
              as_bad (_("Invalid accumulator register."));
1971
 
1972
            case REG_D:
1973
              byte = 0xE6;
1974
              break;
1975
            }
1976
        }
1977
      switch (op->reg2)
1978
        {
1979
        case REG_X:
1980
          break;
1981
 
1982
        case REG_Y:
1983
          byte |= (1 << 3);
1984
          break;
1985
 
1986
        case REG_SP:
1987
          byte |= (2 << 3);
1988
          break;
1989
 
1990
        case REG_PC:
1991
          byte |= (3 << 3);
1992
          break;
1993
 
1994
        default:
1995
          as_bad (_("Invalid indexed register."));
1996
          break;
1997
        }
1998
      f = frag_more (1);
1999
      number_to_chars_bigendian (f, byte, 1);
2000
      return 1;
2001
    }
2002
 
2003
  as_fatal (_("Addressing mode not implemented yet."));
2004
  return 0;
2005
}
2006
 
2007
/* Assemble the 68HC12 register mode byte.  */
2008
static int
2009
build_reg_mode (operand *op, int format)
2010
{
2011
  unsigned char byte;
2012
  char *f;
2013
 
2014
  if (format & M6812_OP_SEX_MARKER
2015
      && op->reg1 != REG_A && op->reg1 != REG_B && op->reg1 != REG_CCR)
2016
    as_bad (_("Invalid source register for this instruction, use 'tfr'."));
2017
  else if (op->reg1 == REG_NONE || op->reg1 == REG_PC)
2018
    as_bad (_("Invalid source register."));
2019
 
2020
  if (format & M6812_OP_SEX_MARKER
2021
      && op->reg2 != REG_D
2022
      && op->reg2 != REG_X && op->reg2 != REG_Y && op->reg2 != REG_SP)
2023
    as_bad (_("Invalid destination register for this instruction, use 'tfr'."));
2024
  else if (op->reg2 == REG_NONE || op->reg2 == REG_PC)
2025
    as_bad (_("Invalid destination register."));
2026
 
2027
  byte = (op->reg1 << 4) | (op->reg2);
2028
  if (format & M6812_OP_EXG_MARKER)
2029
    byte |= 0x80;
2030
 
2031
  f = frag_more (1);
2032
  number_to_chars_bigendian (f, byte, 1);
2033
  return 1;
2034
}
2035
 
2036
/* build_insn takes a pointer to the opcode entry in the opcode table,
2037
   the array of operand expressions and builds the corresponding instruction.
2038
   This operation only deals with non relative jumps insn (need special
2039
   handling).  */
2040
static void
2041
build_insn (struct m68hc11_opcode *opcode, operand operands[],
2042
            int nb_operands ATTRIBUTE_UNUSED)
2043
{
2044
  int i;
2045
  char *f;
2046
  long format;
2047
  int move_insn = 0;
2048
 
2049
  /* Put the page code instruction if there is one.  */
2050
  format = opcode->format;
2051
 
2052
  if (format & M6811_OP_BRANCH)
2053
    fix_new (frag_now, frag_now_fix (), 0,
2054
             &abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
2055
 
2056
  if (format & OP_EXTENDED)
2057
    {
2058
      int page_code;
2059
 
2060
      f = m68hc11_new_insn (2);
2061
      if (format & M6811_OP_PAGE2)
2062
        page_code = M6811_OPCODE_PAGE2;
2063
      else if (format & M6811_OP_PAGE3)
2064
        page_code = M6811_OPCODE_PAGE3;
2065
      else
2066
        page_code = M6811_OPCODE_PAGE4;
2067
 
2068
      number_to_chars_bigendian (f, page_code, 1);
2069
      f++;
2070
    }
2071
  else
2072
    f = m68hc11_new_insn (1);
2073
 
2074
  number_to_chars_bigendian (f, opcode->opcode, 1);
2075
 
2076
  i = 0;
2077
 
2078
  /* The 68HC12 movb and movw instructions are special.  We have to handle
2079
     them in a special way.  */
2080
  if (format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2))
2081
    {
2082
      move_insn = 1;
2083
      if (format & M6812_OP_IDX)
2084
        {
2085
          build_indexed_byte (&operands[0], format, 1);
2086
          i = 1;
2087
          format &= ~M6812_OP_IDX;
2088
        }
2089
      if (format & M6812_OP_IDX_P2)
2090
        {
2091
          build_indexed_byte (&operands[1], format, 1);
2092
          i = 0;
2093
          format &= ~M6812_OP_IDX_P2;
2094
        }
2095
    }
2096
 
2097
  if (format & (M6811_OP_DIRECT | M6811_OP_IMM8))
2098
    {
2099
      fixup8 (&operands[i].exp,
2100
              format & (M6811_OP_DIRECT | M6811_OP_IMM8 | M6812_OP_TRAP_ID),
2101
              operands[i].mode);
2102
      i++;
2103
    }
2104
  else if (IS_CALL_SYMBOL (format) && nb_operands == 1)
2105
    {
2106
      format &= ~M6812_OP_PAGE;
2107
      fixup24 (&operands[i].exp, format & M6811_OP_IND16,
2108
               operands[i].mode);
2109
      i++;
2110
    }
2111
  else if (format & (M6811_OP_IMM16 | M6811_OP_IND16))
2112
    {
2113
      fixup16 (&operands[i].exp,
2114
               format & (M6811_OP_IMM16 | M6811_OP_IND16 | M6812_OP_PAGE),
2115
               operands[i].mode);
2116
      i++;
2117
    }
2118
  else if (format & (M6811_OP_IX | M6811_OP_IY))
2119
    {
2120
      if ((format & M6811_OP_IX) && (operands[0].reg1 != REG_X))
2121
        as_bad (_("Invalid indexed register, expecting register X."));
2122
      if ((format & M6811_OP_IY) && (operands[0].reg1 != REG_Y))
2123
        as_bad (_("Invalid indexed register, expecting register Y."));
2124
 
2125
      fixup8 (&operands[0].exp, M6811_OP_IX, operands[0].mode);
2126
      i = 1;
2127
    }
2128
  else if (format &
2129
           (M6812_OP_IDX | M6812_OP_IDX_2 | M6812_OP_IDX_1
2130
            | M6812_OP_D_IDX | M6812_OP_D_IDX_2))
2131
    {
2132
      build_indexed_byte (&operands[i], format, move_insn);
2133
      i++;
2134
    }
2135
  else if (format & M6812_OP_REG && current_architecture & cpu6812)
2136
    {
2137
      build_reg_mode (&operands[i], format);
2138
      i++;
2139
    }
2140
  if (format & M6811_OP_BITMASK)
2141
    {
2142
      fixup8 (&operands[i].exp, M6811_OP_BITMASK, operands[i].mode);
2143
      i++;
2144
    }
2145
  if (format & M6811_OP_JUMP_REL)
2146
    {
2147
      fixup8 (&operands[i].exp, M6811_OP_JUMP_REL, operands[i].mode);
2148
    }
2149
  else if (format & M6812_OP_IND16_P2)
2150
    {
2151
      fixup16 (&operands[1].exp, M6811_OP_IND16, operands[1].mode);
2152
    }
2153
  if (format & M6812_OP_PAGE)
2154
    {
2155
      fixup8 (&operands[i].exp, M6812_OP_PAGE, operands[i].mode);
2156
    }
2157
}
2158
 
2159
/* Opcode identification and operand analysis.  */
2160
 
2161
/* find() gets a pointer to an entry in the opcode table.  It must look at all
2162
   opcodes with the same name and use the operands to choose the correct
2163
   opcode.  Returns the opcode pointer if there was a match and 0 if none.  */
2164
static struct m68hc11_opcode *
2165
find (struct m68hc11_opcode_def *opc, operand operands[], int nb_operands)
2166
{
2167
  int i, match, pos;
2168
  struct m68hc11_opcode *opcode;
2169
  struct m68hc11_opcode *op_indirect;
2170
 
2171
  op_indirect = 0;
2172
  opcode = opc->opcode;
2173
 
2174
  /* Now search the opcode table table for one with operands
2175
     that matches what we've got.  We're only done if the operands matched so
2176
     far AND there are no more to check.  */
2177
  for (pos = match = 0; match == 0 && pos < opc->nb_modes; pos++, opcode++)
2178
    {
2179
      int poss_indirect = 0;
2180
      long format = opcode->format;
2181
      int expect;
2182
 
2183
      expect = 0;
2184
      if (opcode->format & M6811_OP_MASK)
2185
        expect++;
2186
      if (opcode->format & M6811_OP_BITMASK)
2187
        expect++;
2188
      if (opcode->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
2189
        expect++;
2190
      if (opcode->format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2))
2191
        expect++;
2192
      if ((opcode->format & M6812_OP_PAGE)
2193
          && (!IS_CALL_SYMBOL (opcode->format) || nb_operands == 2))
2194
        expect++;
2195
 
2196
      for (i = 0; expect == nb_operands && i < nb_operands; i++)
2197
        {
2198
          int mode = operands[i].mode;
2199
 
2200
          if (mode & M6811_OP_IMM16)
2201
            {
2202
              if (format &
2203
                  (M6811_OP_IMM8 | M6811_OP_IMM16 | M6811_OP_BITMASK))
2204
                continue;
2205
              break;
2206
            }
2207
          if (mode == M6811_OP_DIRECT)
2208
            {
2209
              if (format & M6811_OP_DIRECT)
2210
                continue;
2211
 
2212
              /* If the operand is a page 0 operand, remember a
2213
                 possible <abs-16> addressing mode.  We mark
2214
                 this and continue to check other operands.  */
2215
              if (format & M6811_OP_IND16
2216
                  && flag_strict_direct_addressing && op_indirect == 0)
2217
                {
2218
                  poss_indirect = 1;
2219
                  continue;
2220
                }
2221
              break;
2222
            }
2223
          if (mode & M6811_OP_IND16)
2224
            {
2225
              if (i == 0 && (format & M6811_OP_IND16) != 0)
2226
                continue;
2227
              if (i != 0 && (format & M6812_OP_PAGE) != 0)
2228
                continue;
2229
              if (i != 0 && (format & M6812_OP_IND16_P2) != 0)
2230
                continue;
2231
              if (i == 0 && (format & M6811_OP_BITMASK))
2232
                break;
2233
            }
2234
          if (mode & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
2235
            {
2236
              if (format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
2237
                continue;
2238
            }
2239
          if (mode & M6812_OP_REG)
2240
            {
2241
              if (i == 0
2242
                  && (format & M6812_OP_REG)
2243
                  && (operands[i].reg2 == REG_NONE))
2244
                continue;
2245
              if (i == 0
2246
                  && (format & M6812_OP_REG)
2247
                  && (format & M6812_OP_REG_2)
2248
                  && (operands[i].reg2 != REG_NONE))
2249
                continue;
2250
              if (i == 0
2251
                  && (format & M6812_OP_IDX)
2252
                  && (operands[i].reg2 != REG_NONE))
2253
                continue;
2254
              if (i == 0
2255
                  && (format & M6812_OP_IDX)
2256
                  && (format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2)))
2257
                continue;
2258
              if (i == 1
2259
                  && (format & M6812_OP_IDX_P2))
2260
                continue;
2261
              break;
2262
            }
2263
          if (mode & M6812_OP_IDX)
2264
            {
2265
              if (format & M6811_OP_IX && operands[i].reg1 == REG_X)
2266
                continue;
2267
              if (format & M6811_OP_IY && operands[i].reg1 == REG_Y)
2268
                continue;
2269
              if (i == 0
2270
                  && format & (M6812_OP_IDX | M6812_OP_IDX_1 | M6812_OP_IDX_2)
2271
                  && (operands[i].reg1 == REG_X
2272
                      || operands[i].reg1 == REG_Y
2273
                      || operands[i].reg1 == REG_SP
2274
                      || operands[i].reg1 == REG_PC))
2275
                continue;
2276
              if (i == 1 && format & M6812_OP_IDX_P2)
2277
                continue;
2278
            }
2279
          if (mode & format & (M6812_OP_D_IDX | M6812_OP_D_IDX_2))
2280
            {
2281
              if (i == 0)
2282
                continue;
2283
            }
2284
          if (mode & M6812_AUTO_INC_DEC)
2285
            {
2286
              if (i == 0
2287
                  && format & (M6812_OP_IDX | M6812_OP_IDX_1 |
2288
                               M6812_OP_IDX_2))
2289
                continue;
2290
              if (i == 1 && format & M6812_OP_IDX_P2)
2291
                continue;
2292
            }
2293
          break;
2294
        }
2295
      match = i == nb_operands;
2296
 
2297
      /* Operands are ok but an operand uses page 0 addressing mode
2298
         while the insn supports abs-16 mode.  Keep a reference to this
2299
         insns in case there is no insn supporting page 0 addressing.  */
2300
      if (match && poss_indirect)
2301
        {
2302
          op_indirect = opcode;
2303
          match = 0;
2304
        }
2305
      if (match)
2306
        break;
2307
    }
2308
 
2309
  /* Page 0 addressing is used but not supported by any insn.
2310
     If absolute addresses are supported, we use that insn.  */
2311
  if (match == 0 && op_indirect)
2312
    {
2313
      opcode = op_indirect;
2314
      match = 1;
2315
    }
2316
 
2317
  if (!match)
2318
    {
2319
      return (0);
2320
    }
2321
 
2322
  return opcode;
2323
}
2324
 
2325
/* Find the real opcode and its associated operands.  We use a progressive
2326
   approach here.  On entry, 'opc' points to the first opcode in the
2327
   table that matches the opcode name in the source line.  We try to
2328
   isolate an operand, find a possible match in the opcode table.
2329
   We isolate another operand if no match were found.  The table 'operands'
2330
   is filled while operands are recognized.
2331
 
2332
   Returns the opcode pointer that matches the opcode name in the
2333
   source line and the associated operands.  */
2334
static struct m68hc11_opcode *
2335
find_opcode (struct m68hc11_opcode_def *opc, operand operands[],
2336
             int *nb_operands)
2337
{
2338
  struct m68hc11_opcode *opcode;
2339
  int i;
2340
 
2341
  if (opc->max_operands == 0)
2342
    {
2343
      *nb_operands = 0;
2344
      return opc->opcode;
2345
    }
2346
 
2347
  for (i = 0; i < opc->max_operands;)
2348
    {
2349
      int result;
2350
 
2351
      result = get_operand (&operands[i], i, opc->format);
2352
      if (result <= 0)
2353
        return 0;
2354
 
2355
      /* Special case where the bitmask of the bclr/brclr
2356
         instructions is not introduced by #.
2357
         Example: bclr 3,x $80.  */
2358
      if (i == 1 && (opc->format & M6811_OP_BITMASK)
2359
          && (operands[i].mode & M6811_OP_IND16))
2360
        {
2361
          operands[i].mode = M6811_OP_IMM16;
2362
        }
2363
 
2364
      i += result;
2365
      *nb_operands = i;
2366
      if (i >= opc->min_operands)
2367
        {
2368
          opcode = find (opc, operands, i);
2369
 
2370
          /* Another special case for 'call foo,page' instructions.
2371
             Since we support 'call foo' and 'call foo,page' we must look
2372
             if the optional page specification is present otherwise we will
2373
             assemble immediately and treat the page spec as garbage.  */
2374
          if (opcode && !(opcode->format & M6812_OP_PAGE))
2375
             return opcode;
2376
 
2377
          if (opcode && *input_line_pointer != ',')
2378
            return opcode;
2379
        }
2380
 
2381
      if (*input_line_pointer == ',')
2382
        input_line_pointer++;
2383
    }
2384
 
2385
  return 0;
2386
}
2387
 
2388
#define M6812_XBCC_MARKER (M6812_OP_TBCC_MARKER \
2389
                           | M6812_OP_DBCC_MARKER \
2390
                           | M6812_OP_IBCC_MARKER)
2391
 
2392
/* Gas line assembler entry point.  */
2393
 
2394
/* This is the main entry point for the machine-dependent assembler.  str
2395
   points to a machine-dependent instruction.  This function is supposed to
2396
   emit the frags/bytes it assembles to.  */
2397
void
2398
md_assemble (char *str)
2399
{
2400
  struct m68hc11_opcode_def *opc;
2401
  struct m68hc11_opcode *opcode;
2402
 
2403
  unsigned char *op_start, *op_end;
2404
  char *save;
2405
  char name[20];
2406
  int nlen = 0;
2407
  operand operands[M6811_MAX_OPERANDS];
2408
  int nb_operands = 0;
2409
  int branch_optimize = 0;
2410
  int alias_id = -1;
2411
 
2412
  /* Drop leading whitespace.  */
2413
  while (*str == ' ')
2414
    str++;
2415
 
2416
  /* Find the opcode end and get the opcode in 'name'.  The opcode is forced
2417
     lower case (the opcode table only has lower case op-codes).  */
2418
  for (op_start = op_end = (unsigned char *) str;
2419
       *op_end && nlen < 20 && !is_end_of_line[*op_end] && *op_end != ' ';
2420
       op_end++)
2421
    {
2422
      name[nlen] = TOLOWER (op_start[nlen]);
2423
      nlen++;
2424
    }
2425
  name[nlen] = 0;
2426
 
2427
  if (nlen == 0)
2428
    {
2429
      as_bad (_("No instruction or missing opcode."));
2430
      return;
2431
    }
2432
 
2433
  /* Find the opcode definition given its name.  */
2434
  opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash, name);
2435
 
2436
  /* If it's not recognized, look for 'jbsr' and 'jbxx'.  These are
2437
     pseudo insns for relative branch.  For these branches, we always
2438
     optimize them (turned into absolute branches) even if --short-branches
2439
     is given.  */
2440
  if (opc == NULL && name[0] == 'j' && name[1] == 'b')
2441
    {
2442
      opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash, &name[1]);
2443
      if (opc
2444
          && (!(opc->format & M6811_OP_JUMP_REL)
2445
              || (opc->format & M6811_OP_BITMASK)))
2446
        opc = 0;
2447
      if (opc)
2448
        branch_optimize = 1;
2449
    }
2450
 
2451
  /* The following test should probably be removed.  This is not conform
2452
     to Motorola assembler specs.  */
2453
  if (opc == NULL && flag_mri)
2454
    {
2455
      if (*op_end == ' ' || *op_end == '\t')
2456
        {
2457
          while (*op_end == ' ' || *op_end == '\t')
2458
            op_end++;
2459
 
2460
          if (nlen < 19
2461
              && (*op_end &&
2462
                  (is_end_of_line[op_end[1]]
2463
                   || op_end[1] == ' ' || op_end[1] == '\t'
2464
                   || !ISALNUM (op_end[1])))
2465
              && (*op_end == 'a' || *op_end == 'b'
2466
                  || *op_end == 'A' || *op_end == 'B'
2467
                  || *op_end == 'd' || *op_end == 'D'
2468
                  || *op_end == 'x' || *op_end == 'X'
2469
                  || *op_end == 'y' || *op_end == 'Y'))
2470
            {
2471
              name[nlen++] = TOLOWER (*op_end++);
2472
              name[nlen] = 0;
2473
              opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash,
2474
                                                             name);
2475
            }
2476
        }
2477
    }
2478
 
2479
  /* Identify a possible instruction alias.  There are some on the
2480
     68HC12 to emulate a few 68HC11 instructions.  */
2481
  if (opc == NULL && (current_architecture & cpu6812))
2482
    {
2483
      int i;
2484
 
2485
      for (i = 0; i < m68hc12_num_alias; i++)
2486
        if (strcmp (m68hc12_alias[i].name, name) == 0)
2487
          {
2488
            alias_id = i;
2489
            break;
2490
          }
2491
    }
2492
  if (opc == NULL && alias_id < 0)
2493
    {
2494
      as_bad (_("Opcode `%s' is not recognized."), name);
2495
      return;
2496
    }
2497
  save = input_line_pointer;
2498
  input_line_pointer = (char *) op_end;
2499
 
2500
  if (opc)
2501
    {
2502
      opc->used++;
2503
      opcode = find_opcode (opc, operands, &nb_operands);
2504
    }
2505
  else
2506
    opcode = 0;
2507
 
2508
  if ((opcode || alias_id >= 0) && !flag_mri)
2509
    {
2510
      char *p = input_line_pointer;
2511
 
2512
      while (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r')
2513
        p++;
2514
 
2515
      if (*p != '\n' && *p)
2516
        as_bad (_("Garbage at end of instruction: `%s'."), p);
2517
    }
2518
 
2519
  input_line_pointer = save;
2520
 
2521
  if (alias_id >= 0)
2522
    {
2523
      char *f = m68hc11_new_insn (m68hc12_alias[alias_id].size);
2524
 
2525
      number_to_chars_bigendian (f, m68hc12_alias[alias_id].code1, 1);
2526
      if (m68hc12_alias[alias_id].size > 1)
2527
        number_to_chars_bigendian (f + 1, m68hc12_alias[alias_id].code2, 1);
2528
 
2529
      return;
2530
    }
2531
 
2532
  /* Opcode is known but does not have valid operands.  Print out the
2533
     syntax for this opcode.  */
2534
  if (opcode == 0)
2535
    {
2536
      if (flag_print_insn_syntax)
2537
        print_insn_format (name);
2538
 
2539
      as_bad (_("Invalid operand for `%s'"), name);
2540
      return;
2541
    }
2542
 
2543
  /* Treat dbeq/ibeq/tbeq instructions in a special way.  The branch is
2544
     relative and must be in the range -256..255 (9-bits).  */
2545
  if ((opcode->format & M6812_XBCC_MARKER)
2546
      && (opcode->format & M6811_OP_JUMP_REL))
2547
    build_dbranch_insn (opcode, operands, nb_operands, branch_optimize);
2548
 
2549
  /* Relative jumps instructions are taken care of separately.  We have to make
2550
     sure that the relative branch is within the range -128..127.  If it's out
2551
     of range, the instructions are changed into absolute instructions.
2552
     This is not supported for the brset and brclr instructions.  */
2553
  else if ((opcode->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
2554
           && !(opcode->format & M6811_OP_BITMASK))
2555
    build_jump_insn (opcode, operands, nb_operands, branch_optimize);
2556
  else
2557
    build_insn (opcode, operands, nb_operands);
2558
}
2559
 
2560
 
2561
/* Pseudo op to control the ELF flags.  */
2562
static void
2563
s_m68hc11_mode (int x ATTRIBUTE_UNUSED)
2564
{
2565
  char *name = input_line_pointer, ch;
2566
 
2567
  while (!is_end_of_line[(unsigned char) *input_line_pointer])
2568
    input_line_pointer++;
2569
  ch = *input_line_pointer;
2570
  *input_line_pointer = '\0';
2571
 
2572
  if (strcmp (name, "mshort") == 0)
2573
    {
2574
      elf_flags &= ~E_M68HC11_I32;
2575
    }
2576
  else if (strcmp (name, "mlong") == 0)
2577
    {
2578
      elf_flags |= E_M68HC11_I32;
2579
    }
2580
  else if (strcmp (name, "mshort-double") == 0)
2581
    {
2582
      elf_flags &= ~E_M68HC11_F64;
2583
    }
2584
  else if (strcmp (name, "mlong-double") == 0)
2585
    {
2586
      elf_flags |= E_M68HC11_F64;
2587
    }
2588
  else
2589
    {
2590
      as_warn (_("Invalid mode: %s\n"), name);
2591
    }
2592
  *input_line_pointer = ch;
2593
  demand_empty_rest_of_line ();
2594
}
2595
 
2596
/* Mark the symbols with STO_M68HC12_FAR to indicate the functions
2597
   are using 'rtc' for returning.  It is necessary to use 'call'
2598
   to invoke them.  This is also used by the debugger to correctly
2599
   find the stack frame.  */
2600
static void
2601
s_m68hc11_mark_symbol (int mark)
2602
{
2603
  char *name;
2604
  int c;
2605
  symbolS *symbolP;
2606
  asymbol *bfdsym;
2607
  elf_symbol_type *elfsym;
2608
 
2609
  do
2610
    {
2611
      name = input_line_pointer;
2612
      c = get_symbol_end ();
2613
      symbolP = symbol_find_or_make (name);
2614
      *input_line_pointer = c;
2615
 
2616
      SKIP_WHITESPACE ();
2617
 
2618
      bfdsym = symbol_get_bfdsym (symbolP);
2619
      elfsym = elf_symbol_from (bfd_asymbol_bfd (bfdsym), bfdsym);
2620
 
2621
      gas_assert (elfsym);
2622
 
2623
      /* Mark the symbol far (using rtc for function return).  */
2624
      elfsym->internal_elf_sym.st_other |= mark;
2625
 
2626
      if (c == ',')
2627
        {
2628
          input_line_pointer ++;
2629
 
2630
          SKIP_WHITESPACE ();
2631
 
2632
          if (*input_line_pointer == '\n')
2633
            c = '\n';
2634
        }
2635
    }
2636
  while (c == ',');
2637
 
2638
  demand_empty_rest_of_line ();
2639
}
2640
 
2641
static void
2642
s_m68hc11_relax (int ignore ATTRIBUTE_UNUSED)
2643
{
2644
  expressionS ex;
2645
 
2646
  expression (&ex);
2647
 
2648
  if (ex.X_op != O_symbol || ex.X_add_number != 0)
2649
    {
2650
      as_bad (_("bad .relax format"));
2651
      ignore_rest_of_line ();
2652
      return;
2653
    }
2654
 
2655
  fix_new_exp (frag_now, frag_now_fix (), 0, &ex, 1,
2656
               BFD_RELOC_M68HC11_RL_GROUP);
2657
 
2658
  demand_empty_rest_of_line ();
2659
}
2660
 
2661
 
2662
/* Relocation, relaxation and frag conversions.  */
2663
 
2664
/* PC-relative offsets are relative to the start of the
2665
   next instruction.  That is, the address of the offset, plus its
2666
   size, since the offset is always the last part of the insn.  */
2667
long
2668
md_pcrel_from (fixS *fixP)
2669
{
2670
  if (fixP->fx_r_type == BFD_RELOC_M68HC11_RL_JUMP)
2671
    return 0;
2672
 
2673
  return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
2674
}
2675
 
2676
/* If while processing a fixup, a reloc really needs to be created
2677
   then it is done here.  */
2678
arelent *
2679
tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
2680
{
2681
  arelent *reloc;
2682
 
2683
  reloc = (arelent *) xmalloc (sizeof (arelent));
2684
  reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
2685
  *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
2686
  reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
2687
  if (fixp->fx_r_type == 0)
2688
    reloc->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_16);
2689
  else
2690
    reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
2691
  if (reloc->howto == (reloc_howto_type *) NULL)
2692
    {
2693
      as_bad_where (fixp->fx_file, fixp->fx_line,
2694
                    _("Relocation %d is not supported by object file format."),
2695
                    (int) fixp->fx_r_type);
2696
      return NULL;
2697
    }
2698
 
2699
  /* Since we use Rel instead of Rela, encode the vtable entry to be
2700
     used in the relocation's section offset.  */
2701
  if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
2702
    reloc->address = fixp->fx_offset;
2703
 
2704
  reloc->addend = 0;
2705
  return reloc;
2706
}
2707
 
2708
/* We need a port-specific relaxation function to cope with sym2 - sym1
2709
   relative expressions with both symbols in the same segment (but not
2710
   necessarily in the same frag as this insn), for example:
2711
     ldab sym2-(sym1-2),pc
2712
    sym1:
2713
   The offset can be 5, 9 or 16 bits long.  */
2714
 
2715
long
2716
m68hc11_relax_frag (segT seg ATTRIBUTE_UNUSED, fragS *fragP,
2717
                    long stretch ATTRIBUTE_UNUSED)
2718
{
2719
  long growth;
2720
  offsetT aim = 0;
2721
  symbolS *symbolP;
2722
  const relax_typeS *this_type;
2723
  const relax_typeS *start_type;
2724
  relax_substateT next_state;
2725
  relax_substateT this_state;
2726
  const relax_typeS *table = TC_GENERIC_RELAX_TABLE;
2727
 
2728
  /* We only have to cope with frags as prepared by
2729
     md_estimate_size_before_relax.  The STATE_BITS16 case may geet here
2730
     because of the different reasons that it's not relaxable.  */
2731
  switch (fragP->fr_subtype)
2732
    {
2733
    case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS16):
2734
    case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16):
2735
      /* When we get to this state, the frag won't grow any more.  */
2736
      return 0;
2737
 
2738
    case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS5):
2739
    case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS5):
2740
    case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS9):
2741
    case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9):
2742
      if (fragP->fr_symbol == NULL
2743
          || S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
2744
        as_fatal (_("internal inconsistency problem in %s: fr_symbol %lx"),
2745
                  __FUNCTION__, (long) fragP->fr_symbol);
2746
      symbolP = fragP->fr_symbol;
2747
      if (symbol_resolved_p (symbolP))
2748
        as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
2749
                  __FUNCTION__);
2750
      aim = S_GET_VALUE (symbolP);
2751
      break;
2752
 
2753
    default:
2754
      as_fatal (_("internal inconsistency problem in %s: fr_subtype %d"),
2755
                  __FUNCTION__, fragP->fr_subtype);
2756
    }
2757
 
2758
  /* The rest is stolen from relax_frag.  There's no obvious way to
2759
     share the code, but fortunately no requirement to keep in sync as
2760
     long as fragP->fr_symbol does not have its segment changed.  */
2761
 
2762
  this_state = fragP->fr_subtype;
2763
  start_type = this_type = table + this_state;
2764
 
2765
  if (aim < 0)
2766
    {
2767
      /* Look backwards.  */
2768
      for (next_state = this_type->rlx_more; next_state;)
2769
        if (aim >= this_type->rlx_backward)
2770
          next_state = 0;
2771
        else
2772
          {
2773
            /* Grow to next state.  */
2774
            this_state = next_state;
2775
            this_type = table + this_state;
2776
            next_state = this_type->rlx_more;
2777
          }
2778
    }
2779
  else
2780
    {
2781
      /* Look forwards.  */
2782
      for (next_state = this_type->rlx_more; next_state;)
2783
        if (aim <= this_type->rlx_forward)
2784
          next_state = 0;
2785
        else
2786
          {
2787
            /* Grow to next state.  */
2788
            this_state = next_state;
2789
            this_type = table + this_state;
2790
            next_state = this_type->rlx_more;
2791
          }
2792
    }
2793
 
2794
  growth = this_type->rlx_length - start_type->rlx_length;
2795
  if (growth != 0)
2796
    fragP->fr_subtype = this_state;
2797
  return growth;
2798
}
2799
 
2800
void
2801
md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, asection *sec ATTRIBUTE_UNUSED,
2802
                 fragS *fragP)
2803
{
2804
  fixS *fixp;
2805
  long value;
2806
  long disp;
2807
  char *buffer_address = fragP->fr_literal;
2808
 
2809
  /* Address in object code of the displacement.  */
2810
  register int object_address = fragP->fr_fix + fragP->fr_address;
2811
 
2812
  buffer_address += fragP->fr_fix;
2813
 
2814
  /* The displacement of the address, from current location.  */
2815
  value = S_GET_VALUE (fragP->fr_symbol);
2816
  disp = (value + fragP->fr_offset) - object_address;
2817
 
2818
  switch (fragP->fr_subtype)
2819
    {
2820
    case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE):
2821
      fragP->fr_opcode[1] = disp;
2822
      break;
2823
 
2824
    case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD):
2825
      /* This relax is only for bsr and bra.  */
2826
      gas_assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
2827
              || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
2828
              || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
2829
 
2830
      fragP->fr_opcode[0] = convert_branch (fragP->fr_opcode[0]);
2831
 
2832
      fix_new (fragP, fragP->fr_fix - 1, 2,
2833
               fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
2834
      fragP->fr_fix += 1;
2835
      break;
2836
 
2837
    case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_BYTE):
2838
    case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_BYTE):
2839
      fragP->fr_opcode[1] = disp;
2840
      break;
2841
 
2842
    case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_WORD):
2843
      /* Invert branch.  */
2844
      fragP->fr_opcode[0] ^= 1;
2845
      fragP->fr_opcode[1] = 3;  /* Branch offset.  */
2846
      buffer_address[0] = M6811_JMP;
2847
      fix_new (fragP, fragP->fr_fix + 1, 2,
2848
               fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
2849
      fragP->fr_fix += 3;
2850
      break;
2851
 
2852
    case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_WORD):
2853
      /* Translate branch into a long branch.  */
2854
      fragP->fr_opcode[1] = fragP->fr_opcode[0];
2855
      fragP->fr_opcode[0] = M6811_OPCODE_PAGE2;
2856
 
2857
      fixp = fix_new (fragP, fragP->fr_fix, 2,
2858
                      fragP->fr_symbol, fragP->fr_offset, 1,
2859
                      BFD_RELOC_16_PCREL);
2860
      fixp->fx_pcrel_adjust = 2;
2861
      fragP->fr_fix += 2;
2862
      break;
2863
 
2864
    case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS5):
2865
      if (fragP->fr_symbol != 0
2866
          && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
2867
        value = disp;
2868
      /* fall through  */
2869
 
2870
    case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS5):
2871
      fragP->fr_opcode[0] = fragP->fr_opcode[0] << 6;
2872
      fragP->fr_opcode[0] |= value & 0x1f;
2873
      break;
2874
 
2875
    case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS9):
2876
      /* For a PC-relative offset, use the displacement with a -1 correction
2877
         to take into account the additional byte of the insn.  */
2878
      if (fragP->fr_symbol != 0
2879
          && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
2880
        value = disp - 1;
2881
      /* fall through  */
2882
 
2883
    case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9):
2884
      fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3);
2885
      fragP->fr_opcode[0] |= 0xE0;
2886
      fragP->fr_opcode[0] |= (value >> 8) & 1;
2887
      fragP->fr_opcode[1] = value;
2888
      fragP->fr_fix += 1;
2889
      break;
2890
 
2891
    case ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_BITS16):
2892
    case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16):
2893
      fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3);
2894
      fragP->fr_opcode[0] |= 0xe2;
2895
      if ((fragP->fr_opcode[0] & 0x0ff) == 0x0fa
2896
          && fragP->fr_symbol != 0
2897
          && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
2898
        {
2899
          fixp = fix_new (fragP, fragP->fr_fix, 2,
2900
                          fragP->fr_symbol, fragP->fr_offset,
2901
                          1, BFD_RELOC_16_PCREL);
2902
        }
2903
      else
2904
        {
2905
          fix_new (fragP, fragP->fr_fix, 2,
2906
                   fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
2907
        }
2908
      fragP->fr_fix += 2;
2909
      break;
2910
 
2911
    case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_BYTE):
2912
      if (disp < 0)
2913
        fragP->fr_opcode[0] |= 0x10;
2914
 
2915
      fragP->fr_opcode[1] = disp & 0x0FF;
2916
      break;
2917
 
2918
    case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_WORD):
2919
      /* Invert branch.  */
2920
      fragP->fr_opcode[0] ^= 0x20;
2921
      fragP->fr_opcode[1] = 3;  /* Branch offset.  */
2922
      buffer_address[0] = M6812_JMP;
2923
      fix_new (fragP, fragP->fr_fix + 1, 2,
2924
               fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
2925
      fragP->fr_fix += 3;
2926
      break;
2927
 
2928
    default:
2929
      break;
2930
    }
2931
}
2932
 
2933
/* On an ELF system, we can't relax a weak symbol.  The weak symbol
2934
   can be overridden at final link time by a non weak symbol.  We can
2935
   relax externally visible symbol because there is no shared library
2936
   and such symbol can't be overridden (unless they are weak).  */
2937
static int
2938
relaxable_symbol (symbolS *symbol)
2939
{
2940
  return ! S_IS_WEAK (symbol);
2941
}
2942
 
2943
/* Force truly undefined symbols to their maximum size, and generally set up
2944
   the frag list to be relaxed.  */
2945
int
2946
md_estimate_size_before_relax (fragS *fragP, asection *segment)
2947
{
2948
  if (RELAX_LENGTH (fragP->fr_subtype) == STATE_UNDF)
2949
    {
2950
      if (S_GET_SEGMENT (fragP->fr_symbol) != segment
2951
          || !relaxable_symbol (fragP->fr_symbol)
2952
          || (segment != absolute_section
2953
              && RELAX_STATE (fragP->fr_subtype) == STATE_INDEXED_OFFSET))
2954
        {
2955
          /* Non-relaxable cases.  */
2956
          int old_fr_fix;
2957
          char *buffer_address;
2958
 
2959
          old_fr_fix = fragP->fr_fix;
2960
          buffer_address = fragP->fr_fix + fragP->fr_literal;
2961
 
2962
          switch (RELAX_STATE (fragP->fr_subtype))
2963
            {
2964
            case STATE_PC_RELATIVE:
2965
 
2966
              /* This relax is only for bsr and bra.  */
2967
              gas_assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
2968
                      || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
2969
                      || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
2970
 
2971
              if (flag_fixed_branches)
2972
                as_bad_where (fragP->fr_file, fragP->fr_line,
2973
                              _("bra or bsr with undefined symbol."));
2974
 
2975
              /* The symbol is undefined or in a separate section.
2976
                 Turn bra into a jmp and bsr into a jsr.  The insn
2977
                 becomes 3 bytes long (instead of 2).  A fixup is
2978
                 necessary for the unresolved symbol address.  */
2979
              fragP->fr_opcode[0] = convert_branch (fragP->fr_opcode[0]);
2980
 
2981
              fix_new (fragP, fragP->fr_fix - 1, 2, fragP->fr_symbol,
2982
                       fragP->fr_offset, 0, BFD_RELOC_16);
2983
              fragP->fr_fix++;
2984
              break;
2985
 
2986
            case STATE_CONDITIONAL_BRANCH:
2987
              gas_assert (current_architecture & cpu6811);
2988
 
2989
              fragP->fr_opcode[0] ^= 1;  /* Reverse sense of branch.  */
2990
              fragP->fr_opcode[1] = 3;  /* Skip next jmp insn (3 bytes).  */
2991
 
2992
              /* Don't use fr_opcode[2] because this may be
2993
                 in a different frag.  */
2994
              buffer_address[0] = M6811_JMP;
2995
 
2996
              fragP->fr_fix++;
2997
              fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
2998
                       fragP->fr_offset, 0, BFD_RELOC_16);
2999
              fragP->fr_fix += 2;
3000
              break;
3001
 
3002
            case STATE_INDEXED_OFFSET:
3003
              gas_assert (current_architecture & cpu6812);
3004
 
3005
              if (fragP->fr_symbol
3006
                  && S_GET_SEGMENT (fragP->fr_symbol) == absolute_section)
3007
                {
3008
                   fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_OFFSET,
3009
                                                     STATE_BITS5);
3010
                   /* Return the size of the variable part of the frag. */
3011
                   return md_relax_table[fragP->fr_subtype].rlx_length;
3012
                }
3013
              else
3014
                {
3015
                   /* Switch the indexed operation to 16-bit mode.  */
3016
                   fragP->fr_opcode[0] = fragP->fr_opcode[0] << 3;
3017
                   fragP->fr_opcode[0] |= 0xe2;
3018
                   fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
3019
                            fragP->fr_offset, 0, BFD_RELOC_16);
3020
                   fragP->fr_fix += 2;
3021
                }
3022
              break;
3023
 
3024
            case STATE_INDEXED_PCREL:
3025
              gas_assert (current_architecture & cpu6812);
3026
 
3027
              if (fragP->fr_symbol
3028
                  && S_GET_SEGMENT (fragP->fr_symbol) == absolute_section)
3029
                {
3030
                   fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_PCREL,
3031
                                                     STATE_BITS5);
3032
                   /* Return the size of the variable part of the frag. */
3033
                   return md_relax_table[fragP->fr_subtype].rlx_length;
3034
                }
3035
              else
3036
                {
3037
                   fixS* fixp;
3038
 
3039
                   fragP->fr_opcode[0] = fragP->fr_opcode[0] << 3;
3040
                   fragP->fr_opcode[0] |= 0xe2;
3041
                   fixp = fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
3042
                                   fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
3043
                   fragP->fr_fix += 2;
3044
                }
3045
              break;
3046
 
3047
            case STATE_XBCC_BRANCH:
3048
              gas_assert (current_architecture & cpu6812);
3049
 
3050
              fragP->fr_opcode[0] ^= 0x20;       /* Reverse sense of branch.  */
3051
              fragP->fr_opcode[1] = 3;  /* Skip next jmp insn (3 bytes).  */
3052
 
3053
              /* Don't use fr_opcode[2] because this may be
3054
                 in a different frag.  */
3055
              buffer_address[0] = M6812_JMP;
3056
 
3057
              fragP->fr_fix++;
3058
              fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
3059
                       fragP->fr_offset, 0, BFD_RELOC_16);
3060
              fragP->fr_fix += 2;
3061
              break;
3062
 
3063
            case STATE_CONDITIONAL_BRANCH_6812:
3064
              gas_assert (current_architecture & cpu6812);
3065
 
3066
              /* Translate into a lbcc branch.  */
3067
              fragP->fr_opcode[1] = fragP->fr_opcode[0];
3068
              fragP->fr_opcode[0] = M6811_OPCODE_PAGE2;
3069
 
3070
              fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
3071
                       fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
3072
              fragP->fr_fix += 2;
3073
              break;
3074
 
3075
            default:
3076
              as_fatal (_("Subtype %d is not recognized."), fragP->fr_subtype);
3077
            }
3078
          frag_wane (fragP);
3079
 
3080
          /* Return the growth in the fixed part of the frag.  */
3081
          return fragP->fr_fix - old_fr_fix;
3082
        }
3083
 
3084
      /* Relaxable cases.  */
3085
      switch (RELAX_STATE (fragP->fr_subtype))
3086
        {
3087
        case STATE_PC_RELATIVE:
3088
          /* This relax is only for bsr and bra.  */
3089
          gas_assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)
3090
                  || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)
3091
                  || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));
3092
 
3093
          fragP->fr_subtype = ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE);
3094
          break;
3095
 
3096
        case STATE_CONDITIONAL_BRANCH:
3097
          gas_assert (current_architecture & cpu6811);
3098
 
3099
          fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH,
3100
                                            STATE_BYTE);
3101
          break;
3102
 
3103
        case STATE_INDEXED_OFFSET:
3104
          gas_assert (current_architecture & cpu6812);
3105
 
3106
          fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_OFFSET,
3107
                                            STATE_BITS5);
3108
          break;
3109
 
3110
        case STATE_INDEXED_PCREL:
3111
          gas_assert (current_architecture & cpu6812);
3112
 
3113
          fragP->fr_subtype = ENCODE_RELAX (STATE_INDEXED_PCREL,
3114
                                            STATE_BITS5);
3115
          break;
3116
 
3117
        case STATE_XBCC_BRANCH:
3118
          gas_assert (current_architecture & cpu6812);
3119
 
3120
          fragP->fr_subtype = ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_BYTE);
3121
          break;
3122
 
3123
        case STATE_CONDITIONAL_BRANCH_6812:
3124
          gas_assert (current_architecture & cpu6812);
3125
 
3126
          fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812,
3127
                                            STATE_BYTE);
3128
          break;
3129
        }
3130
    }
3131
 
3132
  if (fragP->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))
3133
    as_fatal (_("Subtype %d is not recognized."), fragP->fr_subtype);
3134
 
3135
  /* Return the size of the variable part of the frag.  */
3136
  return md_relax_table[fragP->fr_subtype].rlx_length;
3137
}
3138
 
3139
/* See whether we need to force a relocation into the output file.  */
3140
int
3141
tc_m68hc11_force_relocation (fixS *fixP)
3142
{
3143
  if (fixP->fx_r_type == BFD_RELOC_M68HC11_RL_GROUP)
3144
    return 1;
3145
 
3146
  return generic_force_reloc (fixP);
3147
}
3148
 
3149
/* Here we decide which fixups can be adjusted to make them relative
3150
   to the beginning of the section instead of the symbol.  Basically
3151
   we need to make sure that the linker relaxation is done
3152
   correctly, so in some cases we force the original symbol to be
3153
   used.  */
3154
int
3155
tc_m68hc11_fix_adjustable (fixS *fixP)
3156
{
3157
  switch (fixP->fx_r_type)
3158
    {
3159
      /* For the linker relaxation to work correctly, these relocs
3160
         need to be on the symbol itself.  */
3161
    case BFD_RELOC_16:
3162
    case BFD_RELOC_M68HC11_RL_JUMP:
3163
    case BFD_RELOC_M68HC11_RL_GROUP:
3164
    case BFD_RELOC_VTABLE_INHERIT:
3165
    case BFD_RELOC_VTABLE_ENTRY:
3166
    case BFD_RELOC_32:
3167
 
3168
      /* The memory bank addressing translation also needs the original
3169
         symbol.  */
3170
    case BFD_RELOC_M68HC11_LO16:
3171
    case BFD_RELOC_M68HC11_PAGE:
3172
    case BFD_RELOC_M68HC11_24:
3173
      return 0;
3174
 
3175
    default:
3176
      return 1;
3177
    }
3178
}
3179
 
3180
void
3181
md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
3182
{
3183
  char *where;
3184
  long value = * valP;
3185
  int op_type;
3186
 
3187
  if (fixP->fx_addsy == (symbolS *) NULL)
3188
    fixP->fx_done = 1;
3189
 
3190
  /* We don't actually support subtracting a symbol.  */
3191
  if (fixP->fx_subsy != (symbolS *) NULL)
3192
    as_bad_where (fixP->fx_file, fixP->fx_line, _("Expression too complex."));
3193
 
3194
  op_type = fixP->fx_r_type;
3195
 
3196
  /* Patch the instruction with the resolved operand.  Elf relocation
3197
     info will also be generated to take care of linker/loader fixups.
3198
     The 68HC11 addresses only 64Kb, we are only concerned by 8 and 16-bit
3199
     relocs.  BFD_RELOC_8 is basically used for .page0 access (the linker
3200
     will warn for overflows).  BFD_RELOC_8_PCREL should not be generated
3201
     because it's either resolved or turned out into non-relative insns (see
3202
     relax table, bcc, bra, bsr transformations)
3203
 
3204
     The BFD_RELOC_32 is necessary for the support of --gstabs.  */
3205
  where = fixP->fx_frag->fr_literal + fixP->fx_where;
3206
 
3207
  switch (fixP->fx_r_type)
3208
    {
3209
    case BFD_RELOC_32:
3210
      bfd_putb32 ((bfd_vma) value, (unsigned char *) where);
3211
      break;
3212
 
3213
    case BFD_RELOC_24:
3214
    case BFD_RELOC_M68HC11_24:
3215
      bfd_putb16 ((bfd_vma) (value & 0x0ffff), (unsigned char *) where);
3216
      ((bfd_byte*) where)[2] = ((value >> 16) & 0x0ff);
3217
      break;
3218
 
3219
    case BFD_RELOC_16:
3220
    case BFD_RELOC_16_PCREL:
3221
    case BFD_RELOC_M68HC11_LO16:
3222
      bfd_putb16 ((bfd_vma) value, (unsigned char *) where);
3223
      if (value < -65537 || value > 65535)
3224
        as_bad_where (fixP->fx_file, fixP->fx_line,
3225
                      _("Value out of 16-bit range."));
3226
      break;
3227
 
3228
    case BFD_RELOC_M68HC11_HI8:
3229
      value = value >> 8;
3230
      /* Fall through.  */
3231
 
3232
    case BFD_RELOC_M68HC11_LO8:
3233
    case BFD_RELOC_8:
3234
    case BFD_RELOC_M68HC11_PAGE:
3235
      ((bfd_byte *) where)[0] = (bfd_byte) value;
3236
      break;
3237
 
3238
    case BFD_RELOC_8_PCREL:
3239
      ((bfd_byte *) where)[0] = (bfd_byte) value;
3240
 
3241
      if (value < -128 || value > 127)
3242
        as_bad_where (fixP->fx_file, fixP->fx_line,
3243
                      _("Value %ld too large for 8-bit PC-relative branch."),
3244
                      value);
3245
      break;
3246
 
3247
    case BFD_RELOC_M68HC11_3B:
3248
      if (value <= 0 || value > 8)
3249
        as_bad_where (fixP->fx_file, fixP->fx_line,
3250
                      _("Auto increment/decrement offset '%ld' is out of range."),
3251
                      value);
3252
      if (where[0] & 0x8)
3253
        value = 8 - value;
3254
      else
3255
        value--;
3256
 
3257
      where[0] = where[0] | (value & 0x07);
3258
      break;
3259
 
3260
    case BFD_RELOC_M68HC12_5B:
3261
      if (value < -16 || value > 15)
3262
        as_bad_where (fixP->fx_file, fixP->fx_line,
3263
                      _("Offset out of 5-bit range for movw/movb insn: %ld"),
3264
                      value);
3265
      if (value >= 0)
3266
        where[0] |= value;
3267
      else
3268
        where[0] |= (0x10 | (16 + value));
3269
      break;
3270
 
3271
    case BFD_RELOC_M68HC11_RL_JUMP:
3272
    case BFD_RELOC_M68HC11_RL_GROUP:
3273
    case BFD_RELOC_VTABLE_INHERIT:
3274
    case BFD_RELOC_VTABLE_ENTRY:
3275
      fixP->fx_done = 0;
3276
      return;
3277
 
3278
    default:
3279
      as_fatal (_("Line %d: unknown relocation type: 0x%x."),
3280
                fixP->fx_line, fixP->fx_r_type);
3281
    }
3282
}
3283
 
3284
/* Set the ELF specific flags.  */
3285
void
3286
m68hc11_elf_final_processing (void)
3287
{
3288
  if (current_architecture & cpu6812s)
3289
    elf_flags |= EF_M68HCS12_MACH;
3290
  elf_elfheader (stdoutput)->e_flags &= ~EF_M68HC11_ABI;
3291
  elf_elfheader (stdoutput)->e_flags |= elf_flags;
3292
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.