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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [gas/] [config/] [tc-m68hc11.c] - Blame information for rev 120

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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