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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.18.50/] [gas/] [config/] [tc-pdp11.c] - Blame information for rev 179

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

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

powered by: WebSVN 2.1.0

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