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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [binutils-2.20.1/] [gas/] [config/] [tc-pdp11.c] - Blame information for rev 816

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

Line No. Rev Author Line
1 205 julius
/* tc-pdp11.c - pdp11-specific -
2
   Copyright 2001, 2002, 2004, 2005, 2007, 2009
3
   Free Software Foundation, Inc.
4
 
5
   This file is part of GAS, the GNU Assembler.
6
 
7
   GAS is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 3, or (at your option)
10
   any later version.
11
 
12
   GAS is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
 
17
   You should have received a copy of the GNU General Public License
18
   along with GAS; see the file COPYING.  If not, write to
19
   the Free Software Foundation, 51 Franklin Street - Fifth Floor,
20
   Boston, MA 02110-1301, USA.  */
21
 
22
#include "as.h"
23
#include "safe-ctype.h"
24
#include "opcode/pdp11.h"
25
 
26
extern int flonum_gen2vax (int, FLONUM_TYPE * f, LITTLENUM_TYPE *);
27
 
28
#define TRUE  1
29
#define FALSE 0
30
 
31
/* A representation for PDP-11 machine code.  */
32
struct pdp11_code
33
{
34
  char *error;
35
  int code;
36
  int additional;       /* Is there an additional word?  */
37
  int word;             /* Additional word, if any.  */
38
  struct
39
  {
40
    bfd_reloc_code_real_type type;
41
    expressionS exp;
42
    int pc_rel;
43
  } reloc;
44
};
45
 
46
/* Instruction set extensions.
47
 
48
   If you change this from an array to something else, please update
49
   the "PDP-11 instruction set extensions" comment in pdp11.h.  */
50
int pdp11_extension[PDP11_EXT_NUM];
51
 
52
/* Assembly options.  */
53
 
54
#define ASM_OPT_PIC 1
55
#define ASM_OPT_NUM 2
56
 
57
int asm_option[ASM_OPT_NUM];
58
 
59
/* These chars start a comment anywhere in a source file (except inside
60
   another comment.  */
61
const char comment_chars[] = "#/";
62
 
63
/* These chars only start a comment at the beginning of a line.  */
64
const char line_comment_chars[] = "#/";
65
 
66
const char line_separator_chars[] = ";";
67
 
68
/* Chars that can be used to separate mant from exp in floating point nums.  */
69
const char EXP_CHARS[] = "eE";
70
 
71
/* Chars that mean this number is a floating point constant.  */
72
/* as in 0f123.456.  */
73
/* or    0H1.234E-12 (see exp chars above).  */
74
const char FLT_CHARS[] = "dDfF";
75
 
76
void pseudo_even (int);
77
void pseudo_bss (int);
78
 
79
const pseudo_typeS md_pseudo_table[] =
80
{
81
  { "bss", pseudo_bss, 0 },
82
  { "even", pseudo_even, 0 },
83
  { 0, 0, 0 },
84
};
85
 
86
static struct hash_control *insn_hash = NULL;
87
 
88
static int
89
set_option (char *arg)
90
{
91
  int yes = 1;
92
 
93
  if (strcmp (arg, "all-extensions") == 0
94
      || strcmp (arg, "all") == 0)
95
    {
96
      memset (pdp11_extension, ~0, sizeof pdp11_extension);
97
      pdp11_extension[PDP11_NONE] = 0;
98
      return 1;
99
    }
100
  else if (strcmp (arg, "no-extensions") == 0)
101
    {
102
      memset (pdp11_extension, 0, sizeof pdp11_extension);
103
      pdp11_extension[PDP11_BASIC] = 1;
104
      return 1;
105
    }
106
 
107
  if (strncmp (arg, "no-", 3) == 0)
108
    {
109
      yes = 0;
110
      arg += 3;
111
    }
112
 
113
  /* Commersial instructions.  */
114
  if (strcmp (arg, "cis") == 0)
115
    pdp11_extension[PDP11_CIS] = yes;
116
  /* Call supervisor mode.  */
117
  else if (strcmp (arg, "csm") == 0)
118
    pdp11_extension[PDP11_CSM] = yes;
119
  /* Extended instruction set.  */
120
  else if (strcmp (arg, "eis") == 0)
121
    pdp11_extension[PDP11_EIS] = pdp11_extension[PDP11_LEIS] = yes;
122
  /* KEV11 floating-point.  */
123
  else if (strcmp (arg, "fis") == 0
124
           || strcmp (arg, "kev11") == 0
125
           || strcmp (arg, "kev-11") == 0)
126
    pdp11_extension[PDP11_FIS] = yes;
127
  /* FP-11 floating-point.  */
128
  else if (strcmp (arg, "fpp") == 0
129
           || strcmp (arg, "fpu") == 0
130
           || strcmp (arg, "fp11") == 0
131
           || strcmp (arg, "fp-11") == 0
132
           || strcmp (arg, "fpj11") == 0
133
           || strcmp (arg, "fp-j11") == 0
134
           || strcmp (arg, "fpj-11") == 0)
135
    pdp11_extension[PDP11_FPP] = yes;
136
  /* Limited extended insns.  */
137
  else if (strcmp (arg, "limited-eis") == 0)
138
    {
139
      pdp11_extension[PDP11_LEIS] = yes;
140
      if (!pdp11_extension[PDP11_LEIS])
141
        pdp11_extension[PDP11_EIS] = 0;
142
    }
143
  /* Move from processor type.  */
144
  else if (strcmp (arg, "mfpt") == 0)
145
    pdp11_extension[PDP11_MFPT] = yes;
146
  /* Multiprocessor insns:  */
147
  else if (strncmp (arg, "mproc", 5) == 0
148
           /* TSTSET, WRTLCK */
149
           || strncmp (arg, "multiproc", 9) == 0)
150
    pdp11_extension[PDP11_MPROC] = yes;
151
  /* Move from/to proc status.  */
152
  else if (strcmp (arg, "mxps") == 0)
153
    pdp11_extension[PDP11_MXPS] = yes;
154
  /* Position-independent code.  */
155
  else if (strcmp (arg, "pic") == 0)
156
    asm_option[ASM_OPT_PIC] = yes;
157
  /* Set priority level.  */
158
  else if (strcmp (arg, "spl") == 0)
159
    pdp11_extension[PDP11_SPL] = yes;
160
  /* Microcode instructions:  */
161
  else if (strcmp (arg, "ucode") == 0
162
           /* LDUB, MED, XFC */
163
           || strcmp (arg, "microcode") == 0)
164
    pdp11_extension[PDP11_UCODE] = yes;
165
  else
166
    return 0;
167
 
168
  return 1;
169
}
170
 
171
 
172
static void
173
init_defaults (void)
174
{
175
  static int first = 1;
176
 
177
  if (first)
178
    {
179
      set_option ("all-extensions");
180
      set_option ("pic");
181
      first = 0;
182
    }
183
}
184
 
185
void
186
md_begin (void)
187
{
188
  int i;
189
 
190
  init_defaults ();
191
 
192
  insn_hash = hash_new ();
193
  if (insn_hash == NULL)
194
    as_fatal (_("Virtual memory exhausted"));
195
 
196
  for (i = 0; i < pdp11_num_opcodes; i++)
197
    hash_insert (insn_hash, pdp11_opcodes[i].name, (void *) (pdp11_opcodes + i));
198
  for (i = 0; i < pdp11_num_aliases; i++)
199
    hash_insert (insn_hash, pdp11_aliases[i].name, (void *) (pdp11_aliases + i));
200
}
201
 
202
void
203
md_number_to_chars (char con[], valueT value, int nbytes)
204
{
205
  /* On a PDP-11, 0x1234 is stored as "\x12\x34", and
206
     0x12345678 is stored as "\x56\x78\x12\x34". It's
207
     anyones guess what 0x123456 would be stored like.  */
208
 
209
  switch (nbytes)
210
    {
211
    case 0:
212
      break;
213
    case 1:
214
      con[0] =  value       & 0xff;
215
      break;
216
    case 2:
217
      con[0] =  value        & 0xff;
218
      con[1] = (value >>  8) & 0xff;
219
      break;
220
    case 4:
221
      con[0] = (value >> 16) & 0xff;
222
      con[1] = (value >> 24) & 0xff;
223
      con[2] =  value        & 0xff;
224
      con[3] = (value >>  8) & 0xff;
225
      break;
226
    default:
227
      BAD_CASE (nbytes);
228
    }
229
}
230
 
231
/* Fix up some data or instructions after we find out the value of a symbol
232
   that they reference.  Knows about order of bytes in address.  */
233
 
234
void
235
md_apply_fix (fixS *fixP,
236
               valueT * valP,
237
               segT seg ATTRIBUTE_UNUSED)
238
{
239
  valueT code;
240
  valueT mask;
241
  valueT val = * valP;
242
  char *buf;
243
  int shift;
244
  int size;
245
 
246
  buf = fixP->fx_where + fixP->fx_frag->fr_literal;
247
  size = fixP->fx_size;
248
  code = md_chars_to_number ((unsigned char *) buf, size);
249
 
250
  switch (fixP->fx_r_type)
251
    {
252
    case BFD_RELOC_16:
253
    case BFD_RELOC_16_PCREL:
254
      mask = 0xffff;
255
      shift = 0;
256
      break;
257
    case BFD_RELOC_PDP11_DISP_8_PCREL:
258
      mask = 0x00ff;
259
      shift = 1;
260
      break;
261
    case BFD_RELOC_PDP11_DISP_6_PCREL:
262
      mask = 0x003f;
263
      shift = 1;
264
      val = -val;
265
      break;
266
    default:
267
      BAD_CASE (fixP->fx_r_type);
268
    }
269
 
270
  if (fixP->fx_addsy != NULL)
271
    val += symbol_get_bfdsym (fixP->fx_addsy)->section->vma;
272
    /* *value += fixP->fx_addsy->bsym->section->vma; */
273
 
274
  code &= ~mask;
275
  code |= (val >> shift) & mask;
276
  number_to_chars_littleendian (buf, code, size);
277
 
278
  if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
279
    fixP->fx_done = 1;
280
}
281
 
282
long
283
md_chars_to_number (con, nbytes)
284
     unsigned char con[];       /* Low order byte 1st.  */
285
     int nbytes;                /* Number of bytes in the input.  */
286
{
287
  /* On a PDP-11, 0x1234 is stored as "\x12\x34", and
288
     0x12345678 is stored as "\x56\x78\x12\x34". It's
289
     anyones guess what 0x123456 would be stored like.  */
290
  switch (nbytes)
291
    {
292
    case 0:
293
      return 0;
294
    case 1:
295
      return con[0];
296
    case 2:
297
      return (con[1] << BITS_PER_CHAR) | con[0];
298
    case 4:
299
      return
300
        (((con[1] << BITS_PER_CHAR) | con[0]) << (2 * BITS_PER_CHAR))
301
        |((con[3] << BITS_PER_CHAR) | con[2]);
302
    default:
303
      BAD_CASE (nbytes);
304
      return 0;
305
    }
306
}
307
 
308
static char *
309
skip_whitespace (char *str)
310
{
311
  while (*str == ' ' || *str == '\t')
312
    str++;
313
  return str;
314
}
315
 
316
static char *
317
find_whitespace (char *str)
318
{
319
  while (*str != ' ' && *str != '\t' && *str != 0)
320
    str++;
321
  return str;
322
}
323
 
324
static char *
325
parse_reg (char *str, struct pdp11_code *operand)
326
{
327
  str = skip_whitespace (str);
328
  if (TOLOWER (*str) == 'r')
329
    {
330
      str++;
331
      switch (*str)
332
        {
333
        case '0': case '1': case '2': case '3':
334
        case '4': case '5': case '6': case '7':
335
          operand->code = *str - '0';
336
          str++;
337
          break;
338
        default:
339
          operand->error = _("Bad register name");
340
          return str - 1;
341
        }
342
    }
343
  else if (strncmp (str, "sp", 2) == 0
344
           || strncmp (str, "SP", 2) == 0)
345
    {
346
      operand->code = 6;
347
      str += 2;
348
    }
349
  else if (strncmp (str, "pc", 2) == 0
350
           || strncmp (str, "PC", 2) == 0)
351
    {
352
      operand->code = 7;
353
      str += 2;
354
    }
355
  else
356
    {
357
      operand->error = _("Bad register name");
358
      return str;
359
    }
360
 
361
  return str;
362
}
363
 
364
static char *
365
parse_ac5 (char *str, struct pdp11_code *operand)
366
{
367
  str = skip_whitespace (str);
368
  if (strncmp (str, "fr", 2) == 0
369
      || strncmp (str, "FR", 2) == 0
370
      || strncmp (str, "ac", 2) == 0
371
      || strncmp (str, "AC", 2) == 0)
372
    {
373
      str += 2;
374
      switch (*str)
375
        {
376
        case '0': case '1': case '2': case '3':
377
        case '4': case '5':
378
          operand->code = *str - '0';
379
          str++;
380
          break;
381
        default:
382
          operand->error = _("Bad register name");
383
          return str - 2;
384
        }
385
    }
386
  else
387
    {
388
      operand->error = _("Bad register name");
389
      return str;
390
    }
391
 
392
  return str;
393
}
394
 
395
static char *
396
parse_ac (char *str, struct pdp11_code *operand)
397
{
398
  str = parse_ac5 (str, operand);
399
  if (!operand->error && operand->code > 3)
400
    {
401
      operand->error = _("Bad register name");
402
          return str - 3;
403
    }
404
 
405
  return str;
406
}
407
 
408
static char *
409
parse_expression (char *str, struct pdp11_code *operand)
410
{
411
  char *save_input_line_pointer;
412
  segT seg;
413
 
414
  save_input_line_pointer = input_line_pointer;
415
  input_line_pointer = str;
416
  seg = expression (&operand->reloc.exp);
417
  if (seg == NULL)
418
    {
419
      input_line_pointer = save_input_line_pointer;
420
      operand->error = _("Error in expression");
421
      return str;
422
    }
423
 
424
  str = input_line_pointer;
425
  input_line_pointer = save_input_line_pointer;
426
 
427
  operand->reloc.pc_rel = 0;
428
 
429
  return str;
430
}
431
 
432
static char *
433
parse_op_no_deferred (char *str, struct pdp11_code *operand)
434
{
435
  LITTLENUM_TYPE literal_float[2];
436
 
437
  str = skip_whitespace (str);
438
 
439
  switch (*str)
440
    {
441
    case '(':                           /* (rn) and (rn)+ */
442
      str = parse_reg (str + 1, operand);
443
      if (operand->error)
444
        return str;
445
      str = skip_whitespace (str);
446
      if (*str != ')')
447
        {
448
          operand->error = _("Missing ')'");
449
          return str;
450
        }
451
      str++;
452
      if (*str == '+')
453
        {
454
          operand->code |= 020;
455
          str++;
456
        }
457
      else
458
        {
459
          operand->code |= 010;
460
        }
461
      break;
462
 
463
      /* Immediate.  */
464
    case '#':
465
    case '$':
466
      str = parse_expression (str + 1, operand);
467
      if (operand->error)
468
        return str;
469
      operand->additional = TRUE;
470
      operand->word = operand->reloc.exp.X_add_number;
471
      switch (operand->reloc.exp.X_op)
472
        {
473
        case O_constant:
474
          break;
475
        case O_symbol:
476
        case O_add:
477
        case O_subtract:
478
          operand->reloc.type = BFD_RELOC_16;
479
          operand->reloc.pc_rel = 0;
480
          break;
481
        case O_big:
482
          if (operand->reloc.exp.X_add_number > 0)
483
            {
484
              operand->error = _("Error in expression");
485
              break;
486
            }
487
          /* It's a floating literal...  */
488
          know (operand->reloc.exp.X_add_number < 0);
489
          flonum_gen2vax ('f', &generic_floating_point_number, literal_float);
490
          operand->word = literal_float[0];
491
          if (literal_float[1] != 0)
492
            as_warn (_("Low order bits truncated in immediate float operand"));
493
          break;
494
        default:
495
          operand->error = _("Error in expression");
496
          break;
497
        }
498
      operand->code = 027;
499
      break;
500
 
501
      /* label, d(rn), -(rn)  */
502
    default:
503
      {
504
        char *old = str;
505
 
506
        if (strncmp (str, "-(", 2) == 0) /* -(rn) */
507
          {
508
            str = parse_reg (str + 2, operand);
509
            if (operand->error)
510
              return str;
511
            str = skip_whitespace (str);
512
            if (*str != ')')
513
              {
514
                operand->error = _("Missing ')'");
515
                return str;
516
              }
517
            operand->code |= 040;
518
            str++;
519
            break;
520
          }
521
 
522
        str = parse_expression (str, operand);
523
        if (operand->error)
524
          return str;
525
 
526
        str = skip_whitespace (str);
527
 
528
        if (*str != '(')
529
          {
530
            if (operand->reloc.exp.X_op != O_symbol)
531
              {
532
                operand->error = _("Label expected");
533
                return old;
534
              }
535
            operand->code = 067;
536
            operand->additional = 1;
537
            operand->word = 0;
538
            operand->reloc.type = BFD_RELOC_16_PCREL;
539
            operand->reloc.pc_rel = 1;
540
            break;
541
          }
542
 
543
        /* d(rn) */
544
        str++;
545
        str = parse_reg (str, operand);
546
        if (operand->error)
547
          return str;
548
 
549
        str = skip_whitespace (str);
550
 
551
        if (*str != ')')
552
          {
553
            operand->error = _("Missing ')'");
554
            return str;
555
          }
556
 
557
        str++;
558
        operand->additional = TRUE;
559
        operand->code |= 060;
560
        switch (operand->reloc.exp.X_op)
561
          {
562
          case O_symbol:
563
            operand->reloc.type = BFD_RELOC_16;
564
            operand->reloc.pc_rel = 0;
565
            break;
566
          case O_constant:
567
            if ((operand->code & 7) == 7)
568
              {
569
                operand->reloc.pc_rel = 1;
570
                operand->word = operand->reloc.exp.X_add_number;
571
              }
572
            else
573
              operand->word = operand->reloc.exp.X_add_number;
574
 
575
            break;
576
          default:
577
            BAD_CASE (operand->reloc.exp.X_op);
578
          }
579
        break;
580
      }
581
    }
582
 
583
  return str;
584
}
585
 
586
static char *
587
parse_op_noreg (char *str, struct pdp11_code *operand)
588
{
589
  str = skip_whitespace (str);
590
  operand->error = NULL;
591
 
592
  if (*str == '@' || *str == '*')
593
    {
594
      str = parse_op_no_deferred (str + 1, operand);
595
      if (operand->error)
596
        return str;
597
      operand->code |= 010;
598
    }
599
  else
600
    str = parse_op_no_deferred (str, operand);
601
 
602
  return str;
603
}
604
 
605
static char *
606
parse_op (char *str, struct pdp11_code *operand)
607
{
608
  str = skip_whitespace (str);
609
 
610
  str = parse_reg (str, operand);
611
  if (!operand->error)
612
    return str;
613
 
614
  operand->error = NULL;
615
  parse_ac5 (str, operand);
616
  if (!operand->error)
617
    {
618
      operand->error = _("Float AC not legal as integer operand");
619
      return str;
620
    }
621
 
622
  return parse_op_noreg (str, operand);
623
}
624
 
625
static char *
626
parse_fop (char *str, struct pdp11_code *operand)
627
{
628
  str = skip_whitespace (str);
629
 
630
  str = parse_ac5 (str, operand);
631
  if (!operand->error)
632
    return str;
633
 
634
  operand->error = NULL;
635
  parse_reg (str, operand);
636
  if (!operand->error)
637
    {
638
      operand->error = _("General register not legal as float operand");
639
      return str;
640
    }
641
 
642
  return parse_op_noreg (str, operand);
643
}
644
 
645
static char *
646
parse_separator (char *str, int *error)
647
{
648
  str = skip_whitespace (str);
649
  *error = (*str != ',');
650
  if (!*error)
651
    str++;
652
  return str;
653
}
654
 
655
void
656
md_assemble (char *instruction_string)
657
{
658
  const struct pdp11_opcode *op;
659
  struct pdp11_code insn, op1, op2;
660
  int error;
661
  int size;
662
  char *err = NULL;
663
  char *str;
664
  char *p;
665
  char c;
666
 
667
  str = skip_whitespace (instruction_string);
668
  p = find_whitespace (str);
669
  if (p - str == 0)
670
    {
671
      as_bad (_("No instruction found"));
672
      return;
673
    }
674
 
675
  c = *p;
676
  *p = '\0';
677
  op = (struct pdp11_opcode *)hash_find (insn_hash, str);
678
  *p = c;
679
  if (op == 0)
680
    {
681
      as_bad (_("Unknown instruction '%s'"), str);
682
      return;
683
    }
684
 
685
  if (!pdp11_extension[op->extension])
686
    {
687
      as_warn (_("Unsupported instruction set extension: %s"), op->name);
688
      return;
689
    }
690
 
691
  insn.error = NULL;
692
  insn.code = op->opcode;
693
  insn.reloc.type = BFD_RELOC_NONE;
694
  op1.error = NULL;
695
  op1.additional = FALSE;
696
  op1.reloc.type = BFD_RELOC_NONE;
697
  op2.error = NULL;
698
  op2.additional = FALSE;
699
  op2.reloc.type = BFD_RELOC_NONE;
700
 
701
  str = p;
702
  size = 2;
703
 
704
  switch (op->type)
705
    {
706
    case PDP11_OPCODE_NO_OPS:
707
      str = skip_whitespace (str);
708
      if (*str == 0)
709
        str = "";
710
      break;
711
 
712
    case PDP11_OPCODE_IMM3:
713
    case PDP11_OPCODE_IMM6:
714
    case PDP11_OPCODE_IMM8:
715
      str = skip_whitespace (str);
716
      if (*str == '#' || *str == '$')
717
        str++;
718
      str = parse_expression (str, &op1);
719
      if (op1.error)
720
        break;
721
      if (op1.reloc.exp.X_op != O_constant || op1.reloc.type != BFD_RELOC_NONE)
722
        {
723
          op1.error = _("operand is not an absolute constant");
724
          break;
725
        }
726
      switch (op->type)
727
        {
728
        case PDP11_OPCODE_IMM3:
729
          if (op1.reloc.exp.X_add_number & ~7)
730
            {
731
              op1.error = _("3-bit immediate out of range");
732
              break;
733
            }
734
          break;
735
        case PDP11_OPCODE_IMM6:
736
          if (op1.reloc.exp.X_add_number & ~0x3f)
737
            {
738
              op1.error = _("6-bit immediate out of range");
739
              break;
740
            }
741
          break;
742
        case PDP11_OPCODE_IMM8:
743
          if (op1.reloc.exp.X_add_number & ~0xff)
744
            {
745
              op1.error = _("8-bit immediate out of range");
746
              break;
747
            }
748
          break;
749
        }
750
      insn.code |= op1.reloc.exp.X_add_number;
751
      break;
752
 
753
    case PDP11_OPCODE_DISPL:
754
      {
755
        char *new_pointer;
756
        new_pointer = parse_expression (str, &op1);
757
        op1.code = 0;
758
        op1.reloc.pc_rel = 1;
759
        op1.reloc.type = BFD_RELOC_PDP11_DISP_8_PCREL;
760
        if (op1.reloc.exp.X_op != O_symbol)
761
          {
762
            op1.error = _("Symbol expected");
763
            break;
764
          }
765
        if (op1.code & ~0xff)
766
          {
767
            err = _("8-bit displacement out of range");
768
            break;
769
          }
770
        str = new_pointer;
771
        insn.code |= op1.code;
772
        insn.reloc = op1.reloc;
773
      }
774
      break;
775
 
776
    case PDP11_OPCODE_REG:
777
      str = parse_reg (str, &op1);
778
      if (op1.error)
779
        break;
780
      insn.code |= op1.code;
781
      break;
782
 
783
    case PDP11_OPCODE_OP:
784
      str = parse_op (str, &op1);
785
      if (op1.error)
786
        break;
787
      insn.code |= op1.code;
788
      if (op1.additional)
789
        size += 2;
790
      break;
791
 
792
    case PDP11_OPCODE_FOP:
793
      str = parse_fop (str, &op1);
794
      if (op1.error)
795
        break;
796
      insn.code |= op1.code;
797
      if (op1.additional)
798
        size += 2;
799
      break;
800
 
801
    case PDP11_OPCODE_REG_OP:
802
      str = parse_reg (str, &op2);
803
      if (op2.error)
804
        break;
805
      insn.code |= op2.code << 6;
806
      str = parse_separator (str, &error);
807
      if (error)
808
        {
809
          op2.error = _("Missing ','");
810
          break;
811
        }
812
      str = parse_op (str, &op1);
813
      if (op1.error)
814
        break;
815
      insn.code |= op1.code;
816
      if (op1.additional)
817
        size += 2;
818
      break;
819
 
820
    case PDP11_OPCODE_REG_OP_REV:
821
      str = parse_op (str, &op1);
822
      if (op1.error)
823
        break;
824
      insn.code |= op1.code;
825
      if (op1.additional)
826
        size += 2;
827
      str = parse_separator (str, &error);
828
      if (error)
829
        {
830
          op2.error = _("Missing ','");
831
          break;
832
        }
833
      str = parse_reg (str, &op2);
834
      if (op2.error)
835
        break;
836
      insn.code |= op2.code << 6;
837
      break;
838
 
839
    case PDP11_OPCODE_AC_FOP:
840
      str = parse_ac (str, &op2);
841
      if (op2.error)
842
        break;
843
      insn.code |= op2.code << 6;
844
      str = parse_separator (str, &error);
845
      if (error)
846
        {
847
          op1.error = _("Missing ','");
848
          break;
849
        }
850
      str = parse_fop (str, &op1);
851
      if (op1.error)
852
        break;
853
      insn.code |= op1.code;
854
      if (op1.additional)
855
        size += 2;
856
      break;
857
 
858
    case PDP11_OPCODE_FOP_AC:
859
      str = parse_fop (str, &op1);
860
      if (op1.error)
861
        break;
862
      insn.code |= op1.code;
863
      if (op1.additional)
864
        size += 2;
865
      str = parse_separator (str, &error);
866
      if (error)
867
        {
868
          op1.error = _("Missing ','");
869
          break;
870
        }
871
      str = parse_ac (str, &op2);
872
      if (op2.error)
873
        break;
874
      insn.code |= op2.code << 6;
875
      break;
876
 
877
    case PDP11_OPCODE_AC_OP:
878
      str = parse_ac (str, &op2);
879
      if (op2.error)
880
        break;
881
      insn.code |= op2.code << 6;
882
      str = parse_separator (str, &error);
883
      if (error)
884
        {
885
          op1.error = _("Missing ','");
886
          break;
887
        }
888
      str = parse_op (str, &op1);
889
      if (op1.error)
890
        break;
891
      insn.code |= op1.code;
892
      if (op1.additional)
893
        size += 2;
894
      break;
895
 
896
    case PDP11_OPCODE_OP_AC:
897
      str = parse_op (str, &op1);
898
      if (op1.error)
899
        break;
900
      insn.code |= op1.code;
901
      if (op1.additional)
902
        size += 2;
903
      str = parse_separator (str, &error);
904
      if (error)
905
        {
906
          op1.error = _("Missing ','");
907
          break;
908
        }
909
      str = parse_ac (str, &op2);
910
      if (op2.error)
911
        break;
912
      insn.code |= op2.code << 6;
913
      break;
914
 
915
    case PDP11_OPCODE_OP_OP:
916
      str = parse_op (str, &op1);
917
      if (op1.error)
918
        break;
919
      insn.code |= op1.code << 6;
920
      if (op1.additional)
921
        size += 2;
922
      str = parse_separator (str, &error);
923
      if (error)
924
        {
925
          op2.error = _("Missing ','");
926
          break;
927
        }
928
      str = parse_op (str, &op2);
929
      if (op2.error)
930
        break;
931
      insn.code |= op2.code;
932
      if (op2.additional)
933
        size += 2;
934
      break;
935
 
936
    case PDP11_OPCODE_REG_DISPL:
937
      {
938
        char *new_pointer;
939
        str = parse_reg (str, &op2);
940
        if (op2.error)
941
          break;
942
        insn.code |= op2.code << 6;
943
        str = parse_separator (str, &error);
944
        if (error)
945
          {
946
            op1.error = _("Missing ','");
947
            break;
948
          }
949
        new_pointer = parse_expression (str, &op1);
950
        op1.code = 0;
951
        op1.reloc.pc_rel = 1;
952
        op1.reloc.type = BFD_RELOC_PDP11_DISP_6_PCREL;
953
        if (op1.reloc.exp.X_op != O_symbol)
954
          {
955
            op1.error = _("Symbol expected");
956
            break;
957
          }
958
        if (op1.code & ~0x3f)
959
          {
960
            err = _("6-bit displacement out of range");
961
            break;
962
          }
963
        str = new_pointer;
964
        insn.code |= op1.code;
965
        insn.reloc = op1.reloc;
966
      }
967
      break;
968
 
969
    default:
970
      BAD_CASE (op->type);
971
    }
972
 
973
  if (op1.error)
974
    err = op1.error;
975
  else if (op2.error)
976
    err = op2.error;
977
  else
978
    {
979
      str = skip_whitespace (str);
980
      if (*str)
981
        err = _("Too many operands");
982
    }
983
 
984
  {
985
    char *to = NULL;
986
 
987
    if (err)
988
      {
989
        as_bad ("%s", err);
990
        return;
991
      }
992
 
993
    to = frag_more (size);
994
 
995
    md_number_to_chars (to, insn.code, 2);
996
    if (insn.reloc.type != BFD_RELOC_NONE)
997
      fix_new_exp (frag_now, to - frag_now->fr_literal, 2,
998
                   &insn.reloc.exp, insn.reloc.pc_rel, insn.reloc.type);
999
    to += 2;
1000
 
1001
    if (op1.additional)
1002
      {
1003
        md_number_to_chars (to, op1.word, 2);
1004
        if (op1.reloc.type != BFD_RELOC_NONE)
1005
          fix_new_exp (frag_now, to - frag_now->fr_literal, 2,
1006
                       &op1.reloc.exp, op1.reloc.pc_rel, op1.reloc.type);
1007
        to += 2;
1008
      }
1009
 
1010
    if (op2.additional)
1011
      {
1012
        md_number_to_chars (to, op2.word, 2);
1013
        if (op2.reloc.type != BFD_RELOC_NONE)
1014
          fix_new_exp (frag_now, to - frag_now->fr_literal, 2,
1015
                       &op2.reloc.exp, op2.reloc.pc_rel, op2.reloc.type);
1016
      }
1017
  }
1018
}
1019
 
1020
int
1021
md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
1022
                               segT segment ATTRIBUTE_UNUSED)
1023
{
1024
  return 0;
1025
}
1026
 
1027
void
1028
md_convert_frag (bfd *headers ATTRIBUTE_UNUSED,
1029
                 segT seg ATTRIBUTE_UNUSED,
1030
                 fragS *fragP ATTRIBUTE_UNUSED)
1031
{
1032
}
1033
 
1034
int md_short_jump_size = 2;
1035
int md_long_jump_size = 4;
1036
 
1037
void
1038
md_create_short_jump (char *ptr ATTRIBUTE_UNUSED,
1039
                      addressT from_addr ATTRIBUTE_UNUSED,
1040
                      addressT to_addr ATTRIBUTE_UNUSED,
1041
                      fragS *frag ATTRIBUTE_UNUSED,
1042
                      symbolS *to_symbol ATTRIBUTE_UNUSED)
1043
{
1044
}
1045
 
1046
void
1047
md_create_long_jump (char *ptr ATTRIBUTE_UNUSED,
1048
                     addressT from_addr ATTRIBUTE_UNUSED,
1049
                     addressT to_addr ATTRIBUTE_UNUSED,
1050
                     fragS *frag ATTRIBUTE_UNUSED,
1051
                     symbolS *to_symbol ATTRIBUTE_UNUSED)
1052
{
1053
}
1054
 
1055
static int
1056
set_cpu_model (char *arg)
1057
{
1058
  char buf[4];
1059
  char *model = buf;
1060
 
1061
  if (arg[0] == 'k')
1062
    arg++;
1063
 
1064
  *model++ = *arg++;
1065
 
1066
  if (strchr ("abdx", model[-1]) == NULL)
1067
    return 0;
1068
 
1069
  if (model[-1] == 'd')
1070
    {
1071
      if (arg[0] == 'f' || arg[0] == 'j')
1072
        model[-1] = *arg++;
1073
    }
1074
  else if (model[-1] == 'x')
1075
    {
1076
      if (arg[0] == 't')
1077
        model[-1] = *arg++;
1078
    }
1079
 
1080
  if (arg[0] == '-')
1081
    arg++;
1082
 
1083
  if (strncmp (arg, "11", 2) != 0)
1084
    return 0;
1085
  arg += 2;
1086
 
1087
  if (arg[0] == '-')
1088
    {
1089
      if (*++arg == 0)
1090
        return 0;
1091
    }
1092
 
1093
  /* Allow up to two revision letters.  */
1094
  if (arg[0] != 0)
1095
    *model++ = *arg++;
1096
  if (arg[0] != 0)
1097
    *model++ = *arg++;
1098
 
1099
  *model++ = 0;
1100
 
1101
  set_option ("no-extensions");
1102
 
1103
  /* KA11 (11/15/20).  */
1104
  if (strncmp (buf, "a", 1) == 0)
1105
    return 1; /* No extensions.  */
1106
 
1107
  /* KB11 (11/45/50/55/70).  */
1108
  else if (strncmp (buf, "b", 1) == 0)
1109
    return set_option ("eis") && set_option ("spl");
1110
 
1111
  /* KD11-A (11/35/40).  */
1112
  else if (strncmp (buf, "da", 2) == 0)
1113
    return set_option ("limited-eis");
1114
 
1115
  /* KD11-B (11/05/10).  */
1116
  else if (strncmp (buf, "db", 2) == 0
1117
           /* KD11-D (11/04).  */
1118
           || strncmp (buf, "dd", 2) == 0)
1119
    return 1; /* no extensions */
1120
 
1121
  /* KD11-E (11/34).  */
1122
  else if (strncmp (buf, "de", 2) == 0)
1123
    return set_option ("eis") && set_option ("mxps");
1124
 
1125
  /* KD11-F (11/03).  */
1126
  else if (strncmp (buf, "df", 2) == 0
1127
           /* KD11-H (11/03).  */
1128
           || strncmp (buf, "dh", 2) == 0
1129
           /* KD11-Q (11/03).  */
1130
           || strncmp (buf, "dq", 2) == 0)
1131
    return set_option ("limited-eis") && set_option ("mxps");
1132
 
1133
  /* KD11-K (11/60).  */
1134
  else if (strncmp (buf, "dk", 2) == 0)
1135
    return set_option ("eis")
1136
      && set_option ("mxps")
1137
      && set_option ("ucode");
1138
 
1139
  /* KD11-Z (11/44).  */
1140
  else if (strncmp (buf, "dz", 2) == 0)
1141
    return set_option ("csm")
1142
      && set_option ("eis")
1143
      && set_option ("mfpt")
1144
      && set_option ("mxps")
1145
      && set_option ("spl");
1146
 
1147
  /* F11 (11/23/24).  */
1148
  else if (strncmp (buf, "f", 1) == 0)
1149
    return set_option ("eis")
1150
      && set_option ("mfpt")
1151
      && set_option ("mxps");
1152
 
1153
  /* J11 (11/53/73/83/84/93/94).  */
1154
  else if (strncmp (buf, "j", 1) == 0)
1155
    return set_option ("csm")
1156
      && set_option ("eis")
1157
      && set_option ("mfpt")
1158
      && set_option ("multiproc")
1159
      && set_option ("mxps")
1160
      && set_option ("spl");
1161
 
1162
  /* T11 (11/21).  */
1163
  else if (strncmp (buf, "t", 1) == 0)
1164
    return set_option ("limited-eis")
1165
      && set_option ("mxps");
1166
 
1167
  else
1168
    return 0;
1169
}
1170
 
1171
static int
1172
set_machine_model (char *arg)
1173
{
1174
  if (strncmp (arg, "pdp-11/", 7) != 0
1175
      && strncmp (arg, "pdp11/", 6) != 0
1176
      && strncmp (arg, "11/", 3) != 0)
1177
    return 0;
1178
 
1179
  if (strncmp (arg, "pdp", 3) == 0)
1180
    arg += 3;
1181
  if (arg[0] == '-')
1182
    arg++;
1183
  if (strncmp (arg, "11/", 3) == 0)
1184
    arg += 3;
1185
 
1186
  if (strcmp (arg, "03") == 0)
1187
    return set_cpu_model ("kd11f");
1188
 
1189
  else if (strcmp (arg, "04") == 0)
1190
    return set_cpu_model ("kd11d");
1191
 
1192
  else if (strcmp (arg, "05") == 0
1193
           || strcmp (arg, "10") == 0)
1194
    return set_cpu_model ("kd11b");
1195
 
1196
  else if (strcmp (arg, "15") == 0
1197
           || strcmp (arg, "20") == 0)
1198
    return set_cpu_model ("ka11");
1199
 
1200
  else if (strcmp (arg, "21") == 0)
1201
    return set_cpu_model ("t11");
1202
 
1203
  else if (strcmp (arg, "23") == 0
1204
           || strcmp (arg, "24") == 0)
1205
    return set_cpu_model ("f11");
1206
 
1207
  else if (strcmp (arg, "34") == 0
1208
           || strcmp (arg, "34a") == 0)
1209
    return set_cpu_model ("kd11e");
1210
 
1211
  else if (strcmp (arg, "35") == 0
1212
           || strcmp (arg, "40") == 0)
1213
    return set_cpu_model ("kd11da");
1214
 
1215
  else if (strcmp (arg, "44") == 0)
1216
    return set_cpu_model ("kd11dz");
1217
 
1218
  else if (strcmp (arg, "45") == 0
1219
           || strcmp (arg, "50") == 0
1220
           || strcmp (arg, "55") == 0
1221
           || strcmp (arg, "70") == 0)
1222
    return set_cpu_model ("kb11");
1223
 
1224
  else if (strcmp (arg, "60") == 0)
1225
    return set_cpu_model ("kd11k");
1226
 
1227
  else if (strcmp (arg, "53") == 0
1228
           || strcmp (arg, "73") == 0
1229
           || strcmp (arg, "83") == 0
1230
           || strcmp (arg, "84") == 0
1231
           || strcmp (arg, "93") == 0
1232
           || strcmp (arg, "94") == 0)
1233
    return set_cpu_model ("j11")
1234
      && set_option ("fpp");
1235
 
1236
  else
1237
    return 0;
1238
}
1239
 
1240
const char *md_shortopts = "m:";
1241
 
1242
struct option md_longopts[] =
1243
{
1244
#define OPTION_CPU 257
1245
  { "cpu", required_argument, NULL, OPTION_CPU },
1246
#define OPTION_MACHINE 258
1247
  { "machine", required_argument, NULL, OPTION_MACHINE },
1248
#define OPTION_PIC 259
1249
  { "pic", no_argument, NULL, OPTION_PIC },
1250
  { NULL, no_argument, NULL, 0 }
1251
};
1252
 
1253
size_t md_longopts_size = sizeof (md_longopts);
1254
 
1255
/* Invocation line includes a switch not recognized by the base assembler.
1256
   See if it's a processor-specific option.  */
1257
 
1258
int
1259
md_parse_option (int c, char *arg)
1260
{
1261
  init_defaults ();
1262
 
1263
  switch (c)
1264
    {
1265
    case 'm':
1266
      if (set_option (arg))
1267
        return 1;
1268
      if (set_cpu_model (arg))
1269
        return 1;
1270
      if (set_machine_model (arg))
1271
        return 1;
1272
      break;
1273
 
1274
    case OPTION_CPU:
1275
      if (set_cpu_model (arg))
1276
        return 1;
1277
      break;
1278
 
1279
    case OPTION_MACHINE:
1280
      if (set_machine_model (arg))
1281
        return 1;
1282
      break;
1283
 
1284
    case OPTION_PIC:
1285
      if (set_option ("pic"))
1286
        return 1;
1287
      break;
1288
 
1289
    default:
1290
      break;
1291
    }
1292
 
1293
  return 0;
1294
}
1295
 
1296
void
1297
md_show_usage (FILE *stream)
1298
{
1299
  fprintf (stream, "\
1300
\n\
1301
PDP-11 instruction set extentions:\n\
1302
\n\
1303
-m(no-)cis              allow (disallow) commersial instruction set\n\
1304
-m(no-)csm              allow (disallow) CSM instruction\n\
1305
-m(no-)eis              allow (disallow) full extended instruction set\n\
1306
-m(no-)fis              allow (disallow) KEV11 floating-point instructions\n\
1307
-m(no-)fpp              allow (disallow) FP-11 floating-point instructions\n\
1308
-m(no-)fpu              allow (disallow) FP-11 floating-point instructions\n\
1309
-m(no-)limited-eis      allow (disallow) limited extended instruction set\n\
1310
-m(no-)mfpt             allow (disallow) processor type instruction\n\
1311
-m(no-)multiproc        allow (disallow) multiprocessor instructions\n\
1312
-m(no-)mxps             allow (disallow) processor status instructions\n\
1313
-m(no-)spl              allow (disallow) SPL instruction\n\
1314
-m(no-)ucode            allow (disallow) microcode instructions\n\
1315
-mall-extensions        allow all instruction set extensions\n\
1316
                        (this is the default)\n\
1317
-mno-extentions         disallow all instruction set extensions\n\
1318
-pic                    generate position-indepenent code\n\
1319
\n\
1320
PDP-11 CPU model options:\n\
1321
\n\
1322
-mka11*                 KA11 CPU.  base line instruction set only\n\
1323
-mkb11*                 KB11 CPU.  enable full EIS and SPL\n\
1324
-mkd11a*                KD11-A CPU.  enable limited EIS\n\
1325
-mkd11b*                KD11-B CPU.  base line instruction set only\n\
1326
-mkd11d*                KD11-D CPU.  base line instruction set only\n\
1327
-mkd11e*                KD11-E CPU.  enable full EIS, MTPS, and MFPS\n\
1328
-mkd11f*                KD11-F CPU.  enable limited EIS, MTPS, and MFPS\n\
1329
-mkd11h*                KD11-H CPU.  enable limited EIS, MTPS, and MFPS\n\
1330
-mkd11q*                KD11-Q CPU.  enable limited EIS, MTPS, and MFPS\n\
1331
-mkd11k*                KD11-K CPU.  enable full EIS, MTPS, MFPS, LDUB, MED,\n\
1332
                        XFC, and MFPT\n\
1333
-mkd11z*                KD11-Z CPU.  enable full EIS, MTPS, MFPS, MFPT, SPL,\n\
1334
                        and CSM\n\
1335
-mf11*                  F11 CPU.  enable full EIS, MFPS, MTPS, and MFPT\n\
1336
-mj11*                  J11 CPU.  enable full EIS, MTPS, MFPS, MFPT, SPL,\n\
1337
                        CSM, TSTSET, and WRTLCK\n\
1338
-mt11*                  T11 CPU.  enable limited EIS, MTPS, and MFPS\n\
1339
\n\
1340
PDP-11 machine model options:\n\
1341
\n\
1342
-m11/03                 same as -mkd11f\n\
1343
-m11/04                 same as -mkd11d\n\
1344
-m11/05                 same as -mkd11b\n\
1345
-m11/10                 same as -mkd11b\n\
1346
-m11/15                 same as -mka11\n\
1347
-m11/20                 same as -mka11\n\
1348
-m11/21                 same as -mt11\n\
1349
-m11/23                 same as -mf11\n\
1350
-m11/24                 same as -mf11\n\
1351
-m11/34                 same as -mkd11e\n\
1352
-m11/34a                same as -mkd11e -mfpp\n\
1353
-m11/35                 same as -mkd11a\n\
1354
-m11/40                 same as -mkd11a\n\
1355
-m11/44                 same as -mkd11z\n\
1356
-m11/45                 same as -mkb11\n\
1357
-m11/50                 same as -mkb11\n\
1358
-m11/53                 same as -mj11\n\
1359
-m11/55                 same as -mkb11\n\
1360
-m11/60                 same as -mkd11k\n\
1361
-m11/70                 same as -mkb11\n\
1362
-m11/73                 same as -mj11\n\
1363
-m11/83                 same as -mj11\n\
1364
-m11/84                 same as -mj11\n\
1365
-m11/93                 same as -mj11\n\
1366
-m11/94                 same as -mj11\n\
1367
");
1368
}
1369
 
1370
symbolS *
1371
md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
1372
{
1373
  return 0;
1374
}
1375
 
1376
valueT
1377
md_section_align (segT segment ATTRIBUTE_UNUSED,
1378
                  valueT size)
1379
{
1380
  return (size + 1) & ~1;
1381
}
1382
 
1383
long
1384
md_pcrel_from (fixS *fixP)
1385
{
1386
  return fixP->fx_frag->fr_address + fixP->fx_where + fixP->fx_size;
1387
}
1388
 
1389
/* Translate internal representation of relocation info to BFD target
1390
   format.  */
1391
 
1392
arelent *
1393
tc_gen_reloc (asection *section ATTRIBUTE_UNUSED,
1394
              fixS *fixp)
1395
{
1396
  arelent *reloc;
1397
  bfd_reloc_code_real_type code;
1398
 
1399
  reloc = xmalloc (sizeof (* reloc));
1400
 
1401
  reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
1402
  *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1403
  reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1404
 
1405
  /* This is taken account for in md_apply_fix().  */
1406
  reloc->addend = -symbol_get_bfdsym (fixp->fx_addsy)->section->vma;
1407
 
1408
  switch (fixp->fx_r_type)
1409
    {
1410
    case BFD_RELOC_16:
1411
      if (fixp->fx_pcrel)
1412
        code = BFD_RELOC_16_PCREL;
1413
      else
1414
        code = BFD_RELOC_16;
1415
      break;
1416
 
1417
    case BFD_RELOC_16_PCREL:
1418
      code = BFD_RELOC_16_PCREL;
1419
      break;
1420
 
1421
    default:
1422
      BAD_CASE (fixp->fx_r_type);
1423
      return NULL;
1424
    }
1425
 
1426
  reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
1427
 
1428
  if (reloc->howto == NULL)
1429
    {
1430
      as_bad_where (fixp->fx_file, fixp->fx_line,
1431
                    _("Can not represent %s relocation in this object file format"),
1432
                    bfd_get_reloc_code_name (code));
1433
      return NULL;
1434
    }
1435
 
1436
  return reloc;
1437
}
1438
 
1439
void
1440
pseudo_bss (int c ATTRIBUTE_UNUSED)
1441
{
1442
  int temp;
1443
 
1444
  temp = get_absolute_expression ();
1445
  subseg_set (bss_section, temp);
1446
  demand_empty_rest_of_line ();
1447
}
1448
 
1449
void
1450
pseudo_even (int c ATTRIBUTE_UNUSED)
1451
{
1452
  int alignment = 1; /* 2^1 */
1453
  frag_align (alignment, 0, 1);
1454
  record_alignment (now_seg, alignment);
1455
}
1456
 
1457
char *
1458
md_atof (int type, char * litP, int * sizeP)
1459
{
1460
  return vax_md_atof (type, litP, sizeP);
1461
}

powered by: WebSVN 2.1.0

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