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

Subversion Repositories open8_urisc

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

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

Line No. Rev Author Line
1 16 khays
/* 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
        if (strncmp (str, "-(", 2) == 0) /* -(rn) */
505
          {
506
            str = parse_reg (str + 2, operand);
507
            if (operand->error)
508
              return str;
509
            str = skip_whitespace (str);
510
            if (*str != ')')
511
              {
512
                operand->error = _("Missing ')'");
513
                return str;
514
              }
515
            operand->code |= 040;
516
            str++;
517
            break;
518
          }
519
 
520
        str = parse_expression (str, operand);
521
        if (operand->error)
522
          return str;
523
 
524
        str = skip_whitespace (str);
525
 
526
        if (*str != '(')
527
          {
528
            operand->code = 067;
529
            operand->additional = 1;
530
            operand->word = 0;
531
            operand->reloc.type = BFD_RELOC_16_PCREL;
532
            operand->reloc.pc_rel = 1;
533
            break;
534
          }
535
 
536
        /* d(rn) */
537
        str++;
538
        str = parse_reg (str, operand);
539
        if (operand->error)
540
          return str;
541
 
542
        str = skip_whitespace (str);
543
 
544
        if (*str != ')')
545
          {
546
            operand->error = _("Missing ')'");
547
            return str;
548
          }
549
 
550
        str++;
551
        operand->additional = TRUE;
552
        operand->code |= 060;
553
        switch (operand->reloc.exp.X_op)
554
          {
555
          case O_symbol:
556
            operand->reloc.type = BFD_RELOC_16;
557
            operand->reloc.pc_rel = 0;
558
            break;
559
          case O_constant:
560
            if ((operand->code & 7) == 7)
561
              {
562
                operand->reloc.pc_rel = 1;
563
                operand->word = operand->reloc.exp.X_add_number;
564
              }
565
            else
566
              operand->word = operand->reloc.exp.X_add_number;
567
 
568
            break;
569
          default:
570
            BAD_CASE (operand->reloc.exp.X_op);
571
          }
572
        break;
573
      }
574
    }
575
 
576
  return str;
577
}
578
 
579
static char *
580
parse_op_noreg (char *str, struct pdp11_code *operand)
581
{
582
  str = skip_whitespace (str);
583
  operand->error = NULL;
584
 
585
  if (*str == '@' || *str == '*')
586
    {
587
      str = parse_op_no_deferred (str + 1, operand);
588
      if (operand->error)
589
        return str;
590
      operand->code |= 010;
591
    }
592
  else
593
    str = parse_op_no_deferred (str, operand);
594
 
595
  return str;
596
}
597
 
598
static char *
599
parse_op (char *str, struct pdp11_code *operand)
600
{
601
  str = skip_whitespace (str);
602
 
603
  str = parse_reg (str, operand);
604
  if (!operand->error)
605
    return str;
606
 
607
  operand->error = NULL;
608
  parse_ac5 (str, operand);
609
  if (!operand->error)
610
    {
611
      operand->error = _("Float AC not legal as integer operand");
612
      return str;
613
    }
614
 
615
  return parse_op_noreg (str, operand);
616
}
617
 
618
static char *
619
parse_fop (char *str, struct pdp11_code *operand)
620
{
621
  str = skip_whitespace (str);
622
 
623
  str = parse_ac5 (str, operand);
624
  if (!operand->error)
625
    return str;
626
 
627
  operand->error = NULL;
628
  parse_reg (str, operand);
629
  if (!operand->error)
630
    {
631
      operand->error = _("General register not legal as float operand");
632
      return str;
633
    }
634
 
635
  return parse_op_noreg (str, operand);
636
}
637
 
638
static char *
639
parse_separator (char *str, int *error)
640
{
641
  str = skip_whitespace (str);
642
  *error = (*str != ',');
643
  if (!*error)
644
    str++;
645
  return str;
646
}
647
 
648
void
649
md_assemble (char *instruction_string)
650
{
651
  const struct pdp11_opcode *op;
652
  struct pdp11_code insn, op1, op2;
653
  int error;
654
  int size;
655
  char *err = NULL;
656
  char *str;
657
  char *p;
658
  char c;
659
 
660
  str = skip_whitespace (instruction_string);
661
  p = find_whitespace (str);
662
  if (p - str == 0)
663
    {
664
      as_bad (_("No instruction found"));
665
      return;
666
    }
667
 
668
  c = *p;
669
  *p = '\0';
670
  op = (struct pdp11_opcode *)hash_find (insn_hash, str);
671
  *p = c;
672
  if (op == 0)
673
    {
674
      as_bad (_("Unknown instruction '%s'"), str);
675
      return;
676
    }
677
 
678
  if (!pdp11_extension[op->extension])
679
    {
680
      as_warn (_("Unsupported instruction set extension: %s"), op->name);
681
      return;
682
    }
683
 
684
  insn.error = NULL;
685
  insn.code = op->opcode;
686
  insn.reloc.type = BFD_RELOC_NONE;
687
  op1.error = NULL;
688
  op1.additional = FALSE;
689
  op1.reloc.type = BFD_RELOC_NONE;
690
  op2.error = NULL;
691
  op2.additional = FALSE;
692
  op2.reloc.type = BFD_RELOC_NONE;
693
 
694
  str = p;
695
  size = 2;
696
 
697
  switch (op->type)
698
    {
699
    case PDP11_OPCODE_NO_OPS:
700
      str = skip_whitespace (str);
701
      if (*str == 0)
702
        str = "";
703
      break;
704
 
705
    case PDP11_OPCODE_IMM3:
706
    case PDP11_OPCODE_IMM6:
707
    case PDP11_OPCODE_IMM8:
708
      str = skip_whitespace (str);
709
      if (*str == '#' || *str == '$')
710
        str++;
711
      str = parse_expression (str, &op1);
712
      if (op1.error)
713
        break;
714
      if (op1.reloc.exp.X_op != O_constant || op1.reloc.type != BFD_RELOC_NONE)
715
        {
716
          op1.error = _("operand is not an absolute constant");
717
          break;
718
        }
719
      switch (op->type)
720
        {
721
        case PDP11_OPCODE_IMM3:
722
          if (op1.reloc.exp.X_add_number & ~7)
723
            {
724
              op1.error = _("3-bit immediate out of range");
725
              break;
726
            }
727
          break;
728
        case PDP11_OPCODE_IMM6:
729
          if (op1.reloc.exp.X_add_number & ~0x3f)
730
            {
731
              op1.error = _("6-bit immediate out of range");
732
              break;
733
            }
734
          break;
735
        case PDP11_OPCODE_IMM8:
736
          if (op1.reloc.exp.X_add_number & ~0xff)
737
            {
738
              op1.error = _("8-bit immediate out of range");
739
              break;
740
            }
741
          break;
742
        }
743
      insn.code |= op1.reloc.exp.X_add_number;
744
      break;
745
 
746
    case PDP11_OPCODE_DISPL:
747
      {
748
        char *new_pointer;
749
        new_pointer = parse_expression (str, &op1);
750
        op1.code = 0;
751
        op1.reloc.pc_rel = 1;
752
        op1.reloc.type = BFD_RELOC_PDP11_DISP_8_PCREL;
753
        if (op1.reloc.exp.X_op != O_symbol)
754
          {
755
            op1.error = _("Symbol expected");
756
            break;
757
          }
758
        if (op1.code & ~0xff)
759
          {
760
            err = _("8-bit displacement out of range");
761
            break;
762
          }
763
        str = new_pointer;
764
        insn.code |= op1.code;
765
        insn.reloc = op1.reloc;
766
      }
767
      break;
768
 
769
    case PDP11_OPCODE_REG:
770
      str = parse_reg (str, &op1);
771
      if (op1.error)
772
        break;
773
      insn.code |= op1.code;
774
      break;
775
 
776
    case PDP11_OPCODE_OP:
777
      str = parse_op (str, &op1);
778
      if (op1.error)
779
        break;
780
      insn.code |= op1.code;
781
      if (op1.additional)
782
        size += 2;
783
      break;
784
 
785
    case PDP11_OPCODE_FOP:
786
      str = parse_fop (str, &op1);
787
      if (op1.error)
788
        break;
789
      insn.code |= op1.code;
790
      if (op1.additional)
791
        size += 2;
792
      break;
793
 
794
    case PDP11_OPCODE_REG_OP:
795
      str = parse_reg (str, &op2);
796
      if (op2.error)
797
        break;
798
      insn.code |= op2.code << 6;
799
      str = parse_separator (str, &error);
800
      if (error)
801
        {
802
          op2.error = _("Missing ','");
803
          break;
804
        }
805
      str = parse_op (str, &op1);
806
      if (op1.error)
807
        break;
808
      insn.code |= op1.code;
809
      if (op1.additional)
810
        size += 2;
811
      break;
812
 
813
    case PDP11_OPCODE_REG_OP_REV:
814
      str = parse_op (str, &op1);
815
      if (op1.error)
816
        break;
817
      insn.code |= op1.code;
818
      if (op1.additional)
819
        size += 2;
820
      str = parse_separator (str, &error);
821
      if (error)
822
        {
823
          op2.error = _("Missing ','");
824
          break;
825
        }
826
      str = parse_reg (str, &op2);
827
      if (op2.error)
828
        break;
829
      insn.code |= op2.code << 6;
830
      break;
831
 
832
    case PDP11_OPCODE_AC_FOP:
833
      str = parse_ac (str, &op2);
834
      if (op2.error)
835
        break;
836
      insn.code |= op2.code << 6;
837
      str = parse_separator (str, &error);
838
      if (error)
839
        {
840
          op1.error = _("Missing ','");
841
          break;
842
        }
843
      str = parse_fop (str, &op1);
844
      if (op1.error)
845
        break;
846
      insn.code |= op1.code;
847
      if (op1.additional)
848
        size += 2;
849
      break;
850
 
851
    case PDP11_OPCODE_FOP_AC:
852
      str = parse_fop (str, &op1);
853
      if (op1.error)
854
        break;
855
      insn.code |= op1.code;
856
      if (op1.additional)
857
        size += 2;
858
      str = parse_separator (str, &error);
859
      if (error)
860
        {
861
          op1.error = _("Missing ','");
862
          break;
863
        }
864
      str = parse_ac (str, &op2);
865
      if (op2.error)
866
        break;
867
      insn.code |= op2.code << 6;
868
      break;
869
 
870
    case PDP11_OPCODE_AC_OP:
871
      str = parse_ac (str, &op2);
872
      if (op2.error)
873
        break;
874
      insn.code |= op2.code << 6;
875
      str = parse_separator (str, &error);
876
      if (error)
877
        {
878
          op1.error = _("Missing ','");
879
          break;
880
        }
881
      str = parse_op (str, &op1);
882
      if (op1.error)
883
        break;
884
      insn.code |= op1.code;
885
      if (op1.additional)
886
        size += 2;
887
      break;
888
 
889
    case PDP11_OPCODE_OP_AC:
890
      str = parse_op (str, &op1);
891
      if (op1.error)
892
        break;
893
      insn.code |= op1.code;
894
      if (op1.additional)
895
        size += 2;
896
      str = parse_separator (str, &error);
897
      if (error)
898
        {
899
          op1.error = _("Missing ','");
900
          break;
901
        }
902
      str = parse_ac (str, &op2);
903
      if (op2.error)
904
        break;
905
      insn.code |= op2.code << 6;
906
      break;
907
 
908
    case PDP11_OPCODE_OP_OP:
909
      str = parse_op (str, &op1);
910
      if (op1.error)
911
        break;
912
      insn.code |= op1.code << 6;
913
      if (op1.additional)
914
        size += 2;
915
      str = parse_separator (str, &error);
916
      if (error)
917
        {
918
          op2.error = _("Missing ','");
919
          break;
920
        }
921
      str = parse_op (str, &op2);
922
      if (op2.error)
923
        break;
924
      insn.code |= op2.code;
925
      if (op2.additional)
926
        size += 2;
927
      break;
928
 
929
    case PDP11_OPCODE_REG_DISPL:
930
      {
931
        char *new_pointer;
932
        str = parse_reg (str, &op2);
933
        if (op2.error)
934
          break;
935
        insn.code |= op2.code << 6;
936
        str = parse_separator (str, &error);
937
        if (error)
938
          {
939
            op1.error = _("Missing ','");
940
            break;
941
          }
942
        new_pointer = parse_expression (str, &op1);
943
        op1.code = 0;
944
        op1.reloc.pc_rel = 1;
945
        op1.reloc.type = BFD_RELOC_PDP11_DISP_6_PCREL;
946
        if (op1.reloc.exp.X_op != O_symbol)
947
          {
948
            op1.error = _("Symbol expected");
949
            break;
950
          }
951
        if (op1.code & ~0x3f)
952
          {
953
            err = _("6-bit displacement out of range");
954
            break;
955
          }
956
        str = new_pointer;
957
        insn.code |= op1.code;
958
        insn.reloc = op1.reloc;
959
      }
960
      break;
961
 
962
    default:
963
      BAD_CASE (op->type);
964
    }
965
 
966
  if (op1.error)
967
    err = op1.error;
968
  else if (op2.error)
969
    err = op2.error;
970
  else
971
    {
972
      str = skip_whitespace (str);
973
      if (*str)
974
        err = _("Too many operands");
975
    }
976
 
977
  {
978
    char *to = NULL;
979
 
980
    if (err)
981
      {
982
        as_bad ("%s", err);
983
        return;
984
      }
985
 
986
    to = frag_more (size);
987
 
988
    md_number_to_chars (to, insn.code, 2);
989
    if (insn.reloc.type != BFD_RELOC_NONE)
990
      fix_new_exp (frag_now, to - frag_now->fr_literal, 2,
991
                   &insn.reloc.exp, insn.reloc.pc_rel, insn.reloc.type);
992
    to += 2;
993
 
994
    if (op1.additional)
995
      {
996
        md_number_to_chars (to, op1.word, 2);
997
        if (op1.reloc.type != BFD_RELOC_NONE)
998
          fix_new_exp (frag_now, to - frag_now->fr_literal, 2,
999
                       &op1.reloc.exp, op1.reloc.pc_rel, op1.reloc.type);
1000
        to += 2;
1001
      }
1002
 
1003
    if (op2.additional)
1004
      {
1005
        md_number_to_chars (to, op2.word, 2);
1006
        if (op2.reloc.type != BFD_RELOC_NONE)
1007
          fix_new_exp (frag_now, to - frag_now->fr_literal, 2,
1008
                       &op2.reloc.exp, op2.reloc.pc_rel, op2.reloc.type);
1009
      }
1010
  }
1011
}
1012
 
1013
int
1014
md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
1015
                               segT segment ATTRIBUTE_UNUSED)
1016
{
1017
  return 0;
1018
}
1019
 
1020
void
1021
md_convert_frag (bfd *headers ATTRIBUTE_UNUSED,
1022
                 segT seg ATTRIBUTE_UNUSED,
1023
                 fragS *fragP ATTRIBUTE_UNUSED)
1024
{
1025
}
1026
 
1027
int md_short_jump_size = 2;
1028
int md_long_jump_size = 4;
1029
 
1030
void
1031
md_create_short_jump (char *ptr ATTRIBUTE_UNUSED,
1032
                      addressT from_addr ATTRIBUTE_UNUSED,
1033
                      addressT to_addr ATTRIBUTE_UNUSED,
1034
                      fragS *frag ATTRIBUTE_UNUSED,
1035
                      symbolS *to_symbol ATTRIBUTE_UNUSED)
1036
{
1037
}
1038
 
1039
void
1040
md_create_long_jump (char *ptr ATTRIBUTE_UNUSED,
1041
                     addressT from_addr ATTRIBUTE_UNUSED,
1042
                     addressT to_addr ATTRIBUTE_UNUSED,
1043
                     fragS *frag ATTRIBUTE_UNUSED,
1044
                     symbolS *to_symbol ATTRIBUTE_UNUSED)
1045
{
1046
}
1047
 
1048
static int
1049
set_cpu_model (char *arg)
1050
{
1051
  char buf[4];
1052
  char *model = buf;
1053
 
1054
  if (arg[0] == 'k')
1055
    arg++;
1056
 
1057
  *model++ = *arg++;
1058
 
1059
  if (strchr ("abdx", model[-1]) == NULL)
1060
    return 0;
1061
 
1062
  if (model[-1] == 'd')
1063
    {
1064
      if (arg[0] == 'f' || arg[0] == 'j')
1065
        model[-1] = *arg++;
1066
    }
1067
  else if (model[-1] == 'x')
1068
    {
1069
      if (arg[0] == 't')
1070
        model[-1] = *arg++;
1071
    }
1072
 
1073
  if (arg[0] == '-')
1074
    arg++;
1075
 
1076
  if (strncmp (arg, "11", 2) != 0)
1077
    return 0;
1078
  arg += 2;
1079
 
1080
  if (arg[0] == '-')
1081
    {
1082
      if (*++arg == 0)
1083
        return 0;
1084
    }
1085
 
1086
  /* Allow up to two revision letters.  */
1087
  if (arg[0] != 0)
1088
    *model++ = *arg++;
1089
  if (arg[0] != 0)
1090
    *model++ = *arg++;
1091
 
1092
  *model++ = 0;
1093
 
1094
  set_option ("no-extensions");
1095
 
1096
  /* KA11 (11/15/20).  */
1097
  if (strncmp (buf, "a", 1) == 0)
1098
    return 1; /* No extensions.  */
1099
 
1100
  /* KB11 (11/45/50/55/70).  */
1101
  else if (strncmp (buf, "b", 1) == 0)
1102
    return set_option ("eis") && set_option ("spl");
1103
 
1104
  /* KD11-A (11/35/40).  */
1105
  else if (strncmp (buf, "da", 2) == 0)
1106
    return set_option ("limited-eis");
1107
 
1108
  /* KD11-B (11/05/10).  */
1109
  else if (strncmp (buf, "db", 2) == 0
1110
           /* KD11-D (11/04).  */
1111
           || strncmp (buf, "dd", 2) == 0)
1112
    return 1; /* no extensions */
1113
 
1114
  /* KD11-E (11/34).  */
1115
  else if (strncmp (buf, "de", 2) == 0)
1116
    return set_option ("eis") && set_option ("mxps");
1117
 
1118
  /* KD11-F (11/03).  */
1119
  else if (strncmp (buf, "df", 2) == 0
1120
           /* KD11-H (11/03).  */
1121
           || strncmp (buf, "dh", 2) == 0
1122
           /* KD11-Q (11/03).  */
1123
           || strncmp (buf, "dq", 2) == 0)
1124
    return set_option ("limited-eis") && set_option ("mxps");
1125
 
1126
  /* KD11-K (11/60).  */
1127
  else if (strncmp (buf, "dk", 2) == 0)
1128
    return set_option ("eis")
1129
      && set_option ("mxps")
1130
      && set_option ("ucode");
1131
 
1132
  /* KD11-Z (11/44).  */
1133
  else if (strncmp (buf, "dz", 2) == 0)
1134
    return set_option ("csm")
1135
      && set_option ("eis")
1136
      && set_option ("mfpt")
1137
      && set_option ("mxps")
1138
      && set_option ("spl");
1139
 
1140
  /* F11 (11/23/24).  */
1141
  else if (strncmp (buf, "f", 1) == 0)
1142
    return set_option ("eis")
1143
      && set_option ("mfpt")
1144
      && set_option ("mxps");
1145
 
1146
  /* J11 (11/53/73/83/84/93/94).  */
1147
  else if (strncmp (buf, "j", 1) == 0)
1148
    return set_option ("csm")
1149
      && set_option ("eis")
1150
      && set_option ("mfpt")
1151
      && set_option ("multiproc")
1152
      && set_option ("mxps")
1153
      && set_option ("spl");
1154
 
1155
  /* T11 (11/21).  */
1156
  else if (strncmp (buf, "t", 1) == 0)
1157
    return set_option ("limited-eis")
1158
      && set_option ("mxps");
1159
 
1160
  else
1161
    return 0;
1162
}
1163
 
1164
static int
1165
set_machine_model (char *arg)
1166
{
1167
  if (strncmp (arg, "pdp-11/", 7) != 0
1168
      && strncmp (arg, "pdp11/", 6) != 0
1169
      && strncmp (arg, "11/", 3) != 0)
1170
    return 0;
1171
 
1172
  if (strncmp (arg, "pdp", 3) == 0)
1173
    arg += 3;
1174
  if (arg[0] == '-')
1175
    arg++;
1176
  if (strncmp (arg, "11/", 3) == 0)
1177
    arg += 3;
1178
 
1179
  if (strcmp (arg, "03") == 0)
1180
    return set_cpu_model ("kd11f");
1181
 
1182
  else if (strcmp (arg, "04") == 0)
1183
    return set_cpu_model ("kd11d");
1184
 
1185
  else if (strcmp (arg, "05") == 0
1186
           || strcmp (arg, "10") == 0)
1187
    return set_cpu_model ("kd11b");
1188
 
1189
  else if (strcmp (arg, "15") == 0
1190
           || strcmp (arg, "20") == 0)
1191
    return set_cpu_model ("ka11");
1192
 
1193
  else if (strcmp (arg, "21") == 0)
1194
    return set_cpu_model ("t11");
1195
 
1196
  else if (strcmp (arg, "23") == 0
1197
           || strcmp (arg, "24") == 0)
1198
    return set_cpu_model ("f11");
1199
 
1200
  else if (strcmp (arg, "34") == 0
1201
           || strcmp (arg, "34a") == 0)
1202
    return set_cpu_model ("kd11e");
1203
 
1204
  else if (strcmp (arg, "35") == 0
1205
           || strcmp (arg, "40") == 0)
1206
    return set_cpu_model ("kd11da");
1207
 
1208
  else if (strcmp (arg, "44") == 0)
1209
    return set_cpu_model ("kd11dz");
1210
 
1211
  else if (strcmp (arg, "45") == 0
1212
           || strcmp (arg, "50") == 0
1213
           || strcmp (arg, "55") == 0
1214
           || strcmp (arg, "70") == 0)
1215
    return set_cpu_model ("kb11");
1216
 
1217
  else if (strcmp (arg, "60") == 0)
1218
    return set_cpu_model ("kd11k");
1219
 
1220
  else if (strcmp (arg, "53") == 0
1221
           || strcmp (arg, "73") == 0
1222
           || strcmp (arg, "83") == 0
1223
           || strcmp (arg, "84") == 0
1224
           || strcmp (arg, "93") == 0
1225
           || strcmp (arg, "94") == 0)
1226
    return set_cpu_model ("j11")
1227
      && set_option ("fpp");
1228
 
1229
  else
1230
    return 0;
1231
}
1232
 
1233
const char *md_shortopts = "m:";
1234
 
1235
struct option md_longopts[] =
1236
{
1237
#define OPTION_CPU 257
1238
  { "cpu", required_argument, NULL, OPTION_CPU },
1239
#define OPTION_MACHINE 258
1240
  { "machine", required_argument, NULL, OPTION_MACHINE },
1241
#define OPTION_PIC 259
1242
  { "pic", no_argument, NULL, OPTION_PIC },
1243
  { NULL, no_argument, NULL, 0 }
1244
};
1245
 
1246
size_t md_longopts_size = sizeof (md_longopts);
1247
 
1248
/* Invocation line includes a switch not recognized by the base assembler.
1249
   See if it's a processor-specific option.  */
1250
 
1251
int
1252
md_parse_option (int c, char *arg)
1253
{
1254
  init_defaults ();
1255
 
1256
  switch (c)
1257
    {
1258
    case 'm':
1259
      if (set_option (arg))
1260
        return 1;
1261
      if (set_cpu_model (arg))
1262
        return 1;
1263
      if (set_machine_model (arg))
1264
        return 1;
1265
      break;
1266
 
1267
    case OPTION_CPU:
1268
      if (set_cpu_model (arg))
1269
        return 1;
1270
      break;
1271
 
1272
    case OPTION_MACHINE:
1273
      if (set_machine_model (arg))
1274
        return 1;
1275
      break;
1276
 
1277
    case OPTION_PIC:
1278
      if (set_option ("pic"))
1279
        return 1;
1280
      break;
1281
 
1282
    default:
1283
      break;
1284
    }
1285
 
1286
  return 0;
1287
}
1288
 
1289
void
1290
md_show_usage (FILE *stream)
1291
{
1292
  fprintf (stream, "\
1293
\n\
1294
PDP-11 instruction set extentions:\n\
1295
\n\
1296
-m(no-)cis              allow (disallow) commersial instruction set\n\
1297
-m(no-)csm              allow (disallow) CSM instruction\n\
1298
-m(no-)eis              allow (disallow) full extended instruction set\n\
1299
-m(no-)fis              allow (disallow) KEV11 floating-point instructions\n\
1300
-m(no-)fpp              allow (disallow) FP-11 floating-point instructions\n\
1301
-m(no-)fpu              allow (disallow) FP-11 floating-point instructions\n\
1302
-m(no-)limited-eis      allow (disallow) limited extended instruction set\n\
1303
-m(no-)mfpt             allow (disallow) processor type instruction\n\
1304
-m(no-)multiproc        allow (disallow) multiprocessor instructions\n\
1305
-m(no-)mxps             allow (disallow) processor status instructions\n\
1306
-m(no-)spl              allow (disallow) SPL instruction\n\
1307
-m(no-)ucode            allow (disallow) microcode instructions\n\
1308
-mall-extensions        allow all instruction set extensions\n\
1309
                        (this is the default)\n\
1310
-mno-extentions         disallow all instruction set extensions\n\
1311
-pic                    generate position-indepenent code\n\
1312
\n\
1313
PDP-11 CPU model options:\n\
1314
\n\
1315
-mka11*                 KA11 CPU.  base line instruction set only\n\
1316
-mkb11*                 KB11 CPU.  enable full EIS and SPL\n\
1317
-mkd11a*                KD11-A CPU.  enable limited EIS\n\
1318
-mkd11b*                KD11-B CPU.  base line instruction set only\n\
1319
-mkd11d*                KD11-D CPU.  base line instruction set only\n\
1320
-mkd11e*                KD11-E CPU.  enable full EIS, MTPS, and MFPS\n\
1321
-mkd11f*                KD11-F CPU.  enable limited EIS, MTPS, and MFPS\n\
1322
-mkd11h*                KD11-H CPU.  enable limited EIS, MTPS, and MFPS\n\
1323
-mkd11q*                KD11-Q CPU.  enable limited EIS, MTPS, and MFPS\n\
1324
-mkd11k*                KD11-K CPU.  enable full EIS, MTPS, MFPS, LDUB, MED,\n\
1325
                        XFC, and MFPT\n\
1326
-mkd11z*                KD11-Z CPU.  enable full EIS, MTPS, MFPS, MFPT, SPL,\n\
1327
                        and CSM\n\
1328
-mf11*                  F11 CPU.  enable full EIS, MFPS, MTPS, and MFPT\n\
1329
-mj11*                  J11 CPU.  enable full EIS, MTPS, MFPS, MFPT, SPL,\n\
1330
                        CSM, TSTSET, and WRTLCK\n\
1331
-mt11*                  T11 CPU.  enable limited EIS, MTPS, and MFPS\n\
1332
\n\
1333
PDP-11 machine model options:\n\
1334
\n\
1335
-m11/03                 same as -mkd11f\n\
1336
-m11/04                 same as -mkd11d\n\
1337
-m11/05                 same as -mkd11b\n\
1338
-m11/10                 same as -mkd11b\n\
1339
-m11/15                 same as -mka11\n\
1340
-m11/20                 same as -mka11\n\
1341
-m11/21                 same as -mt11\n\
1342
-m11/23                 same as -mf11\n\
1343
-m11/24                 same as -mf11\n\
1344
-m11/34                 same as -mkd11e\n\
1345
-m11/34a                same as -mkd11e -mfpp\n\
1346
-m11/35                 same as -mkd11a\n\
1347
-m11/40                 same as -mkd11a\n\
1348
-m11/44                 same as -mkd11z\n\
1349
-m11/45                 same as -mkb11\n\
1350
-m11/50                 same as -mkb11\n\
1351
-m11/53                 same as -mj11\n\
1352
-m11/55                 same as -mkb11\n\
1353
-m11/60                 same as -mkd11k\n\
1354
-m11/70                 same as -mkb11\n\
1355
-m11/73                 same as -mj11\n\
1356
-m11/83                 same as -mj11\n\
1357
-m11/84                 same as -mj11\n\
1358
-m11/93                 same as -mj11\n\
1359
-m11/94                 same as -mj11\n\
1360
");
1361
}
1362
 
1363
symbolS *
1364
md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
1365
{
1366
  return 0;
1367
}
1368
 
1369
valueT
1370
md_section_align (segT segment ATTRIBUTE_UNUSED,
1371
                  valueT size)
1372
{
1373
  return (size + 1) & ~1;
1374
}
1375
 
1376
long
1377
md_pcrel_from (fixS *fixP)
1378
{
1379
  return fixP->fx_frag->fr_address + fixP->fx_where + fixP->fx_size;
1380
}
1381
 
1382
/* Translate internal representation of relocation info to BFD target
1383
   format.  */
1384
 
1385
arelent *
1386
tc_gen_reloc (asection *section ATTRIBUTE_UNUSED,
1387
              fixS *fixp)
1388
{
1389
  arelent *reloc;
1390
  bfd_reloc_code_real_type code;
1391
 
1392
  reloc = xmalloc (sizeof (* reloc));
1393
 
1394
  reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
1395
  *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1396
  reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1397
 
1398
  /* This is taken account for in md_apply_fix().  */
1399
  reloc->addend = -symbol_get_bfdsym (fixp->fx_addsy)->section->vma;
1400
 
1401
  switch (fixp->fx_r_type)
1402
    {
1403
    case BFD_RELOC_16:
1404
      if (fixp->fx_pcrel)
1405
        code = BFD_RELOC_16_PCREL;
1406
      else
1407
        code = BFD_RELOC_16;
1408
      break;
1409
 
1410
    case BFD_RELOC_16_PCREL:
1411
      code = BFD_RELOC_16_PCREL;
1412
      break;
1413
 
1414
    default:
1415
      BAD_CASE (fixp->fx_r_type);
1416
      return NULL;
1417
    }
1418
 
1419
  reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
1420
 
1421
  if (reloc->howto == NULL)
1422
    {
1423
      as_bad_where (fixp->fx_file, fixp->fx_line,
1424
                    _("Can not represent %s relocation in this object file format"),
1425
                    bfd_get_reloc_code_name (code));
1426
      return NULL;
1427
    }
1428
 
1429
  return reloc;
1430
}
1431
 
1432
void
1433
pseudo_bss (int c ATTRIBUTE_UNUSED)
1434
{
1435
  int temp;
1436
 
1437
  temp = get_absolute_expression ();
1438
  subseg_set (bss_section, temp);
1439
  demand_empty_rest_of_line ();
1440
}
1441
 
1442
void
1443
pseudo_even (int c ATTRIBUTE_UNUSED)
1444
{
1445
  int alignment = 1; /* 2^1 */
1446
  frag_align (alignment, 0, 1);
1447
  record_alignment (now_seg, alignment);
1448
}
1449
 
1450
char *
1451
md_atof (int type, char * litP, int * sizeP)
1452
{
1453
  return vax_md_atof (type, litP, sizeP);
1454
}

powered by: WebSVN 2.1.0

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