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

Subversion Repositories openrisc

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

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

Line No. Rev Author Line
1 205 julius
/* ns32k.c  -- Assemble on the National Semiconductor 32k series
2
   Copyright 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3
   2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009
4
   Free Software Foundation, Inc.
5
 
6
   This file is part of GAS, the GNU Assembler.
7
 
8
   GAS is free software; you can redistribute it and/or modify
9
   it under the terms of the GNU General Public License as published by
10
   the Free Software Foundation; either version 3, or (at your option)
11
   any later version.
12
 
13
   GAS is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
 
18
   You should have received a copy of the GNU General Public License
19
   along with GAS; see the file COPYING.  If not, write to the Free
20
   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
21
   02110-1301, USA.  */
22
 
23
/*#define SHOW_NUM 1*//* Uncomment for debugging.  */
24
 
25
#include "as.h"
26
#include "opcode/ns32k.h"
27
 
28
#include "obstack.h"
29
 
30
/* Macros.  */
31
#define IIF_ENTRIES 13          /* Number of entries in iif.  */
32
#define PRIVATE_SIZE 256        /* Size of my garbage memory.  */
33
#define MAX_ARGS 4
34
#define DEFAULT -1              /* addr_mode returns this value when
35
                                   plain constant or label is
36
                                   encountered.  */
37
 
38
#define IIF(ptr,a1,c1,e1,g1,i1,k1,m1,o1,q1,s1,u1)       \
39
    iif.iifP[ptr].type = a1;                            \
40
    iif.iifP[ptr].size = c1;                            \
41
    iif.iifP[ptr].object = e1;                          \
42
    iif.iifP[ptr].object_adjust = g1;                   \
43
    iif.iifP[ptr].pcrel = i1;                           \
44
    iif.iifP[ptr].pcrel_adjust = k1;                    \
45
    iif.iifP[ptr].im_disp = m1;                         \
46
    iif.iifP[ptr].relax_substate = o1;                  \
47
    iif.iifP[ptr].bit_fixP = q1;                        \
48
    iif.iifP[ptr].addr_mode = s1;                       \
49
    iif.iifP[ptr].bsr = u1;
50
 
51
#ifdef SEQUENT_COMPATABILITY
52
#define LINE_COMMENT_CHARS "|"
53
#define ABSOLUTE_PREFIX '@'
54
#define IMMEDIATE_PREFIX '#'
55
#endif
56
 
57
#ifndef LINE_COMMENT_CHARS
58
#define LINE_COMMENT_CHARS "#"
59
#endif
60
 
61
const char comment_chars[] = "#";
62
const char line_comment_chars[] = LINE_COMMENT_CHARS;
63
const char line_separator_chars[] = ";";
64
static int default_disp_size = 4; /* Displacement size for external refs.  */
65
 
66
#if !defined(ABSOLUTE_PREFIX) && !defined(IMMEDIATE_PREFIX)
67
#define ABSOLUTE_PREFIX '@'     /* One or the other MUST be defined.  */
68
#endif
69
 
70
struct addr_mode
71
{
72
  signed char mode;             /* Addressing mode of operand (0-31).  */
73
  signed char scaled_mode;      /* Mode combined with scaled mode.  */
74
  char scaled_reg;              /* Register used in scaled+1 (1-8).  */
75
  char float_flag;              /* Set if R0..R7 was F0..F7 ie a
76
                                   floating-point-register.  */
77
  char am_size;                 /* Estimated max size of general addr-mode
78
                                   parts.  */
79
  char im_disp;                 /* If im_disp==1 we have a displacement.  */
80
  char pcrel;                   /* 1 if pcrel, this is really redundant info.  */
81
  char disp_suffix[2];          /* Length of displacement(s), 0=undefined.  */
82
  char *disp[2];                /* Pointer(s) at displacement(s)
83
                                   or immediates(s)     (ascii).  */
84
  char index_byte;              /* Index byte.  */
85
};
86
typedef struct addr_mode addr_modeS;
87
 
88
char *freeptr, *freeptr_static; /* Points at some number of free bytes.  */
89
struct hash_control *inst_hash_handle;
90
 
91
struct ns32k_opcode *desc;      /* Pointer at description of instruction.  */
92
addr_modeS addr_modeP;
93
const char EXP_CHARS[] = "eE";
94
const char FLT_CHARS[] = "fd";  /* We don't want to support lowercase,
95
                                   do we?  */
96
 
97
/* UPPERCASE denotes live names when an instruction is built, IIF is
98
   used as an intermediate form to store the actual parts of the
99
   instruction. A ns32k machine instruction can be divided into a
100
   couple of sub PARTs. When an instruction is assembled the
101
   appropriate PART get an assignment. When an IIF has been completed
102
   it is converted to a FRAGment as specified in AS.H.  */
103
 
104
/* Internal structs.  */
105
struct ns32k_option
106
{
107
  char *pattern;
108
  unsigned long or;
109
  unsigned long and;
110
};
111
 
112
typedef struct
113
{
114
  int type;                     /* How to interpret object.  */
115
  int size;                     /* Estimated max size of object.  */
116
  unsigned long object;         /* Binary data.  */
117
  int object_adjust;            /* Number added to object.  */
118
  int pcrel;                    /* True if object is pcrel.  */
119
  int pcrel_adjust;             /* Length in bytes from the instruction
120
                                   start to the displacement.  */
121
  int im_disp;                  /* True if the object is a displacement.  */
122
  relax_substateT relax_substate;/*Initial relaxsubstate.  */
123
  bit_fixS *bit_fixP;           /* Pointer at bit_fix struct.  */
124
  int addr_mode;                /* What addrmode do we associate with this
125
                                   iif-entry.  */
126
  char bsr;                     /* Sequent hack.  */
127
} iif_entryT;                   /* Internal Instruction Format.  */
128
 
129
struct int_ins_form
130
{
131
  int instr_size;               /* Max size of instruction in bytes.  */
132
  iif_entryT iifP[IIF_ENTRIES + 1];
133
};
134
 
135
struct int_ins_form iif;
136
expressionS exprP;
137
char *input_line_pointer;
138
 
139
/* Description of the PARTs in IIF
140
  object[n]:
141
 
142
   1    opcode
143
   2    index_byte_a
144
   3    index_byte_b
145
   4    disp_a_1
146
   5    disp_a_2
147
   6    disp_b_1
148
   7    disp_b_2
149
   8    imm_a
150
   9    imm_b
151
   10   implied1
152
   11   implied2
153
 
154
   For every entry there is a datalength in bytes. This is stored in size[n].
155
         0,     the objectlength is not explicitly given by the instruction
156
                and the operand is undefined. This is a case for relaxation.
157
                Reserve 4 bytes for the final object.
158
 
159
         1,     the entry contains one byte
160
         2,     the entry contains two bytes
161
         3,     the entry contains three bytes
162
         4,     the entry contains four bytes
163
        etc
164
 
165
   Furthermore, every entry has a data type identifier in type[n].
166
 
167
         0,     the entry is void, ignore it.
168
         1,     the entry is a binary number.
169
         2,     the entry is a pointer at an expression.
170
                Where expression may be as simple as a single '1',
171
                and as complicated as  foo-bar+12,
172
                foo and bar may be undefined but suffixed by :{b|w|d} to
173
                control the length of the object.
174
 
175
         3,     the entry is a pointer at a bignum struct
176
 
177
   The low-order-byte corresponds to low physical memory.
178
   Obviously a FRAGment must be created for each valid disp in PART whose
179
   datalength is undefined (to bad) .
180
   The case where just the expression is undefined is less severe and is
181
   handled by fix. Here the number of bytes in the objectfile is known.
182
   With this representation we simplify the assembly and separates the
183
   machine dependent/independent parts in a more clean way (said OE).  */
184
 
185
struct ns32k_option opt1[] =            /* restore, exit.  */
186
{
187
  {"r0", 0x80, 0xff},
188
  {"r1", 0x40, 0xff},
189
  {"r2", 0x20, 0xff},
190
  {"r3", 0x10, 0xff},
191
  {"r4", 0x08, 0xff},
192
  {"r5", 0x04, 0xff},
193
  {"r6", 0x02, 0xff},
194
  {"r7", 0x01, 0xff},
195
  {0, 0x00, 0xff}
196
};
197
struct ns32k_option opt2[] =            /* save, enter.  */
198
{
199
  {"r0", 0x01, 0xff},
200
  {"r1", 0x02, 0xff},
201
  {"r2", 0x04, 0xff},
202
  {"r3", 0x08, 0xff},
203
  {"r4", 0x10, 0xff},
204
  {"r5", 0x20, 0xff},
205
  {"r6", 0x40, 0xff},
206
  {"r7", 0x80, 0xff},
207
  {0, 0x00, 0xff}
208
};
209
struct ns32k_option opt3[] =            /* setcfg.  */
210
{
211
  {"c", 0x8, 0xff},
212
  {"m", 0x4, 0xff},
213
  {"f", 0x2, 0xff},
214
  {"i", 0x1, 0xff},
215
  {0, 0x0, 0xff}
216
};
217
struct ns32k_option opt4[] =            /* cinv.  */
218
{
219
  {"a", 0x4, 0xff},
220
  {"i", 0x2, 0xff},
221
  {"d", 0x1, 0xff},
222
  {0, 0x0, 0xff}
223
};
224
struct ns32k_option opt5[] =            /* String inst.  */
225
{
226
  {"b", 0x2, 0xff},
227
  {"u", 0xc, 0xff},
228
  {"w", 0x4, 0xff},
229
  {0, 0x0, 0xff}
230
};
231
struct ns32k_option opt6[] =            /* Plain reg ext,cvtp etc.  */
232
{
233
  {"r0", 0x00, 0xff},
234
  {"r1", 0x01, 0xff},
235
  {"r2", 0x02, 0xff},
236
  {"r3", 0x03, 0xff},
237
  {"r4", 0x04, 0xff},
238
  {"r5", 0x05, 0xff},
239
  {"r6", 0x06, 0xff},
240
  {"r7", 0x07, 0xff},
241
  {0, 0x00, 0xff}
242
};
243
 
244
#if !defined(NS32032) && !defined(NS32532)
245
#define NS32532
246
#endif
247
 
248
struct ns32k_option cpureg_532[] =      /* lpr spr.  */
249
{
250
  {"us", 0x0, 0xff},
251
  {"dcr", 0x1, 0xff},
252
  {"bpc", 0x2, 0xff},
253
  {"dsr", 0x3, 0xff},
254
  {"car", 0x4, 0xff},
255
  {"fp", 0x8, 0xff},
256
  {"sp", 0x9, 0xff},
257
  {"sb", 0xa, 0xff},
258
  {"usp", 0xb, 0xff},
259
  {"cfg", 0xc, 0xff},
260
  {"psr", 0xd, 0xff},
261
  {"intbase", 0xe, 0xff},
262
  {"mod", 0xf, 0xff},
263
  {0, 0x00, 0xff}
264
};
265
struct ns32k_option mmureg_532[] =      /* lmr smr.  */
266
{
267
  {"mcr", 0x9, 0xff},
268
  {"msr", 0xa, 0xff},
269
  {"tear", 0xb, 0xff},
270
  {"ptb0", 0xc, 0xff},
271
  {"ptb1", 0xd, 0xff},
272
  {"ivar0", 0xe, 0xff},
273
  {"ivar1", 0xf, 0xff},
274
  {0, 0x0, 0xff}
275
};
276
 
277
struct ns32k_option cpureg_032[] =      /* lpr spr.  */
278
{
279
  {"upsr", 0x0, 0xff},
280
  {"fp", 0x8, 0xff},
281
  {"sp", 0x9, 0xff},
282
  {"sb", 0xa, 0xff},
283
  {"psr", 0xd, 0xff},
284
  {"intbase", 0xe, 0xff},
285
  {"mod", 0xf, 0xff},
286
  {0, 0x0, 0xff}
287
};
288
struct ns32k_option mmureg_032[] =      /* lmr smr.  */
289
{
290
  {"bpr0", 0x0, 0xff},
291
  {"bpr1", 0x1, 0xff},
292
  {"pf0", 0x4, 0xff},
293
  {"pf1", 0x5, 0xff},
294
  {"sc", 0x8, 0xff},
295
  {"msr", 0xa, 0xff},
296
  {"bcnt", 0xb, 0xff},
297
  {"ptb0", 0xc, 0xff},
298
  {"ptb1", 0xd, 0xff},
299
  {"eia", 0xf, 0xff},
300
  {0, 0x0, 0xff}
301
};
302
 
303
#if defined(NS32532)
304
struct ns32k_option *cpureg = cpureg_532;
305
struct ns32k_option *mmureg = mmureg_532;
306
#else
307
struct ns32k_option *cpureg = cpureg_032;
308
struct ns32k_option *mmureg = mmureg_032;
309
#endif
310
 
311
 
312
const pseudo_typeS md_pseudo_table[] =
313
{                                       /* So far empty.  */
314
  {0, 0, 0}
315
};
316
 
317
#define IND(x,y)        (((x)<<2)+(y))
318
 
319
/* Those are index's to relax groups in md_relax_table ie it must be
320
   multiplied by 4 to point at a group start. Viz IND(x,y) Se function
321
   relax_segment in write.c for more info.  */
322
 
323
#define BRANCH          1
324
#define PCREL           2
325
 
326
/* Those are index's to entries in a relax group.  */
327
 
328
#define BYTE            0
329
#define WORD            1
330
#define DOUBLE          2
331
#define UNDEF           3
332
/* Those limits are calculated from the displacement start in memory.
333
   The ns32k uses the beginning of the instruction as displacement
334
   base.  This type of displacements could be handled here by moving
335
   the limit window up or down. I choose to use an internal
336
   displacement base-adjust as there are other routines that must
337
   consider this. Also, as we have two various offset-adjusts in the
338
   ns32k (acb versus br/brs/jsr/bcond), two set of limits would have
339
   had to be used.  Now we dont have to think about that.  */
340
 
341
const relax_typeS md_relax_table[] =
342
{
343
  {1, 1, 0, 0},
344
  {1, 1, 0, 0},
345
  {1, 1, 0, 0},
346
  {1, 1, 0, 0},
347
 
348
  {(63), (-64), 1, IND (BRANCH, WORD)},
349
  {(8192), (-8192), 2, IND (BRANCH, DOUBLE)},
350
  {0, 0, 4, 0},
351
  {1, 1, 0, 0}
352
};
353
 
354
/* Array used to test if mode contains displacements.
355
   Value is true if mode contains displacement.  */
356
 
357
char disp_test[] =
358
{0, 0, 0, 0, 0, 0, 0, 0,
359
 1, 1, 1, 1, 1, 1, 1, 1,
360
 1, 1, 1, 0, 0, 1, 1, 0,
361
 1, 1, 1, 1, 1, 1, 1, 1};
362
 
363
/* Array used to calculate max size of displacements.  */
364
 
365
char disp_size[] =
366
{4, 1, 2, 0, 4};
367
 
368
/* Parse a general operand into an addressingmode struct
369
 
370
   In:  pointer at operand in ascii form
371
        pointer at addr_mode struct for result
372
        the level of recursion. (always 0 or 1)
373
 
374
   Out: data in addr_mode struct.  */
375
 
376
static int
377
addr_mode (char *operand,
378
           addr_modeS *addr_modeP,
379
           int recursive_level)
380
{
381
  char *str;
382
  int i;
383
  int strl;
384
  int mode;
385
  int j;
386
 
387
  mode = DEFAULT;               /* Default.  */
388
  addr_modeP->scaled_mode = 0;   /* Why not.  */
389
  addr_modeP->scaled_reg = 0;    /* If 0, not scaled index.  */
390
  addr_modeP->float_flag = 0;
391
  addr_modeP->am_size = 0;
392
  addr_modeP->im_disp = 0;
393
  addr_modeP->pcrel = 0; /* Not set in this function.  */
394
  addr_modeP->disp_suffix[0] = 0;
395
  addr_modeP->disp_suffix[1] = 0;
396
  addr_modeP->disp[0] = NULL;
397
  addr_modeP->disp[1] = NULL;
398
  str = operand;
399
 
400
  if (str[0] == 0)
401
    return 0;
402
 
403
  strl = strlen (str);
404
 
405
  switch (str[0])
406
    {
407
      /* The following three case statements controls the mode-chars
408
         this is the place to ed if you want to change them.  */
409
#ifdef ABSOLUTE_PREFIX
410
    case ABSOLUTE_PREFIX:
411
      if (str[strl - 1] == ']')
412
        break;
413
      addr_modeP->mode = 21;    /* absolute */
414
      addr_modeP->disp[0] = str + 1;
415
      return -1;
416
#endif
417
#ifdef IMMEDIATE_PREFIX
418
    case IMMEDIATE_PREFIX:
419
      if (str[strl - 1] == ']')
420
        break;
421
      addr_modeP->mode = 20;    /* immediate */
422
      addr_modeP->disp[0] = str + 1;
423
      return -1;
424
#endif
425
    case '.':
426
      if (str[strl - 1] != ']')
427
        {
428
          switch (str[1])
429
            {
430
            case '-':
431
            case '+':
432
              if (str[2] != '\000')
433
                {
434
                  addr_modeP->mode = 27;        /* pc-relative */
435
                  addr_modeP->disp[0] = str + 2;
436
                  return -1;
437
                }
438
            default:
439
              as_bad (_("Invalid syntax in PC-relative addressing mode"));
440
              return 0;
441
            }
442
        }
443
      break;
444
    case 'e':
445
      if (str[strl - 1] != ']')
446
        {
447
          if ((!strncmp (str, "ext(", 4)) && strl > 7)
448
            {                           /* external */
449
              addr_modeP->disp[0] = str + 4;
450
              i = 0;
451
              j = 2;
452
              do
453
                {                       /* disp[0]'s termination point.  */
454
                  j += 1;
455
                  if (str[j] == '(')
456
                    i++;
457
                  if (str[j] == ')')
458
                    i--;
459
                }
460
              while (j < strl && i != 0);
461
              if (i != 0 || !(str[j + 1] == '-' || str[j + 1] == '+'))
462
                {
463
                  as_bad (_("Invalid syntax in External addressing mode"));
464
                  return (0);
465
                }
466
              str[j] = '\000';          /* null terminate disp[0] */
467
              addr_modeP->disp[1] = str + j + 2;
468
              addr_modeP->mode = 22;
469
              return -1;
470
            }
471
        }
472
      break;
473
 
474
    default:
475
      ;
476
    }
477
 
478
  strl = strlen (str);
479
 
480
  switch (strl)
481
    {
482
    case 2:
483
      switch (str[0])
484
        {
485
        case 'f':
486
          addr_modeP->float_flag = 1;
487
          /* Drop through.  */
488
        case 'r':
489
          if (str[1] >= '0' && str[1] < '8')
490
            {
491
              addr_modeP->mode = str[1] - '0';
492
              return -1;
493
            }
494
          break;
495
        default:
496
          break;
497
        }
498
      /* Drop through.  */
499
 
500
    case 3:
501
      if (!strncmp (str, "tos", 3))
502
        {
503
          addr_modeP->mode = 23;        /* TopOfStack */
504
          return -1;
505
        }
506
      break;
507
 
508
    default:
509
      break;
510
    }
511
 
512
  if (strl > 4)
513
    {
514
      if (str[strl - 1] == ')')
515
        {
516
          if (str[strl - 2] == ')')
517
            {
518
              if (!strncmp (&str[strl - 5], "(fp", 3))
519
                mode = 16;              /* Memory Relative.  */
520
              else if (!strncmp (&str[strl - 5], "(sp", 3))
521
                mode = 17;
522
              else if (!strncmp (&str[strl - 5], "(sb", 3))
523
                mode = 18;
524
 
525
              if (mode != DEFAULT)
526
                {
527
                  /* Memory relative.  */
528
                  addr_modeP->mode = mode;
529
                  j = strl - 5;         /* Temp for end of disp[0].  */
530
                  i = 0;
531
 
532
                  do
533
                    {
534
                      strl -= 1;
535
                      if (str[strl] == ')')
536
                        i++;
537
                      if (str[strl] == '(')
538
                        i--;
539
                    }
540
                  while (strl > -1 && i != 0);
541
 
542
                  if (i != 0)
543
                    {
544
                      as_bad (_("Invalid syntax in Memory Relative addressing mode"));
545
                      return (0);
546
                    }
547
 
548
                  addr_modeP->disp[1] = str;
549
                  addr_modeP->disp[0] = str + strl + 1;
550
                  str[j] = '\000';      /* Null terminate disp[0] .  */
551
                  str[strl] = '\000';   /* Null terminate disp[1].  */
552
 
553
                  return -1;
554
                }
555
            }
556
 
557
          switch (str[strl - 3])
558
            {
559
            case 'r':
560
            case 'R':
561
              if (str[strl - 2] >= '0'
562
                  && str[strl - 2] < '8'
563
                  && str[strl - 4] == '(')
564
                {
565
                  addr_modeP->mode = str[strl - 2] - '0' + 8;
566
                  addr_modeP->disp[0] = str;
567
                  str[strl - 4] = 0;
568
                  return -1;            /* reg rel */
569
                }
570
              /* Drop through.  */
571
 
572
            default:
573
              if (!strncmp (&str[strl - 4], "(fp", 3))
574
                mode = 24;
575
              else if (!strncmp (&str[strl - 4], "(sp", 3))
576
                mode = 25;
577
              else if (!strncmp (&str[strl - 4], "(sb", 3))
578
                mode = 26;
579
              else if (!strncmp (&str[strl - 4], "(pc", 3))
580
                mode = 27;
581
 
582
              if (mode != DEFAULT)
583
                {
584
                  addr_modeP->mode = mode;
585
                  addr_modeP->disp[0] = str;
586
                  str[strl - 4] = '\0';
587
 
588
                  return -1;            /* Memory space.  */
589
                }
590
            }
591
        }
592
 
593
      /* No trailing ')' do we have a ']' ?  */
594
      if (str[strl - 1] == ']')
595
        {
596
          switch (str[strl - 2])
597
            {
598
            case 'b':
599
              mode = 28;
600
              break;
601
            case 'w':
602
              mode = 29;
603
              break;
604
            case 'd':
605
              mode = 30;
606
              break;
607
            case 'q':
608
              mode = 31;
609
              break;
610
            default:
611
              as_bad (_("Invalid scaled-indexed mode, use (b,w,d,q)"));
612
 
613
              if (str[strl - 3] != ':' || str[strl - 6] != '['
614
                  || str[strl - 5] == 'r' || str[strl - 4] < '0'
615
                  || str[strl - 4] > '7')
616
                as_bad (_("Syntax in scaled-indexed mode, use [Rn:m] where n=[0..7] m={b,w,d,q}"));
617
            } /* Scaled index.  */
618
 
619
          if (recursive_level > 0)
620
            {
621
              as_bad (_("Scaled-indexed addressing mode combined with scaled-index"));
622
              return 0;
623
            }
624
 
625
          addr_modeP->am_size += 1;     /* scaled index byte.  */
626
          j = str[strl - 4] - '0';      /* store temporary.  */
627
          str[strl - 6] = '\000';       /* nullterminate for recursive call.  */
628
          i = addr_mode (str, addr_modeP, 1);
629
 
630
          if (!i || addr_modeP->mode == 20)
631
            {
632
              as_bad (_("Invalid or illegal addressing mode combined with scaled-index"));
633
              return 0;
634
            }
635
 
636
          addr_modeP->scaled_mode = addr_modeP->mode;   /* Store the inferior mode.  */
637
          addr_modeP->mode = mode;
638
          addr_modeP->scaled_reg = j + 1;
639
 
640
          return -1;
641
        }
642
    }
643
 
644
  addr_modeP->mode = DEFAULT;   /* Default to whatever.  */
645
  addr_modeP->disp[0] = str;
646
 
647
  return -1;
648
}
649
 
650
static void
651
evaluate_expr (expressionS *resultP, char *ptr)
652
{
653
  char *tmp_line;
654
 
655
  tmp_line = input_line_pointer;
656
  input_line_pointer = ptr;
657
  expression (resultP);
658
  input_line_pointer = tmp_line;
659
}
660
 
661
/* ptr points at string addr_modeP points at struct with result This
662
   routine calls addr_mode to determine the general addr.mode of the
663
   operand. When this is ready it parses the displacements for size
664
   specifying suffixes and determines size of immediate mode via
665
   ns32k-opcode.  Also builds index bytes if needed.  */
666
 
667
static int
668
get_addr_mode (char *ptr, addr_modeS *addr_modeP)
669
{
670
  int tmp;
671
 
672
  addr_mode (ptr, addr_modeP, 0);
673
 
674
  if (addr_modeP->mode == DEFAULT || addr_modeP->scaled_mode == -1)
675
    {
676
      /* Resolve ambiguous operands, this shouldn't be necessary if
677
         one uses standard NSC operand syntax. But the sequent
678
         compiler doesn't!!!  This finds a proper addressing mode
679
         if it is implicitly stated. See ns32k-opcode.h.  */
680
      (void) evaluate_expr (&exprP, ptr); /* This call takes time Sigh!  */
681
 
682
      if (addr_modeP->mode == DEFAULT)
683
        {
684
          if (exprP.X_add_symbol || exprP.X_op_symbol)
685
            addr_modeP->mode = desc->default_model; /* We have a label.  */
686
          else
687
            addr_modeP->mode = desc->default_modec; /* We have a constant.  */
688
        }
689
      else
690
        {
691
          if (exprP.X_add_symbol || exprP.X_op_symbol)
692
            addr_modeP->scaled_mode = desc->default_model;
693
          else
694
            addr_modeP->scaled_mode = desc->default_modec;
695
        }
696
 
697
      /* Must put this mess down in addr_mode to handle the scaled
698
         case better.  */
699
    }
700
 
701
  /* It appears as the sequent compiler wants an absolute when we have
702
     a label without @. Constants becomes immediates besides the addr
703
     case.  Think it does so with local labels too, not optimum, pcrel
704
     is better.  When I have time I will make gas check this and
705
     select pcrel when possible Actually that is trivial.  */
706
  if ((tmp = addr_modeP->scaled_reg))
707
    {                           /* Build indexbyte.  */
708
      tmp--;                    /* Remember regnumber comes incremented for
709
                                   flagpurpose.  */
710
      tmp |= addr_modeP->scaled_mode << 3;
711
      addr_modeP->index_byte = (char) tmp;
712
      addr_modeP->am_size += 1;
713
    }
714
 
715
  gas_assert (addr_modeP->mode >= 0);
716
  if (disp_test[(unsigned int) addr_modeP->mode])
717
    {
718
      char c;
719
      char suffix;
720
      char suffix_sub;
721
      int i;
722
      char *toP;
723
      char *fromP;
724
 
725
      /* There was a displacement, probe for length  specifying suffix.  */
726
      addr_modeP->pcrel = 0;
727
 
728
      gas_assert (addr_modeP->mode >= 0);
729
      if (disp_test[(unsigned int) addr_modeP->mode])
730
        {
731
          /* There is a displacement.  */
732
          if (addr_modeP->mode == 27 || addr_modeP->scaled_mode == 27)
733
            /* Do we have pcrel. mode.  */
734
            addr_modeP->pcrel = 1;
735
 
736
          addr_modeP->im_disp = 1;
737
 
738
          for (i = 0; i < 2; i++)
739
            {
740
              suffix_sub = suffix = 0;
741
 
742
              if ((toP = addr_modeP->disp[i]))
743
                {
744
                  /* Suffix of expression, the largest size rules.  */
745
                  fromP = toP;
746
 
747
                  while ((c = *fromP++))
748
                    {
749
                      *toP++ = c;
750
                      if (c == ':')
751
                        {
752
                          switch (*fromP)
753
                            {
754
                            case '\0':
755
                              as_warn (_("Premature end of suffix -- Defaulting to d"));
756
                              suffix = 4;
757
                              continue;
758
                            case 'b':
759
                              suffix_sub = 1;
760
                              break;
761
                            case 'w':
762
                              suffix_sub = 2;
763
                              break;
764
                            case 'd':
765
                              suffix_sub = 4;
766
                              break;
767
                            default:
768
                              as_warn (_("Bad suffix after ':' use {b|w|d} Defaulting to d"));
769
                              suffix = 4;
770
                            }
771
 
772
                          fromP ++;
773
                          toP --;       /* So we write over the ':' */
774
 
775
                          if (suffix < suffix_sub)
776
                            suffix = suffix_sub;
777
                        }
778
                    }
779
 
780
                  *toP = '\0'; /* Terminate properly.  */
781
                  addr_modeP->disp_suffix[i] = suffix;
782
                  addr_modeP->am_size += suffix ? suffix : 4;
783
                }
784
            }
785
        }
786
    }
787
  else
788
    {
789
      if (addr_modeP->mode == 20)
790
        {
791
          /* Look in ns32k_opcode for size.  */
792
          addr_modeP->disp_suffix[0] = addr_modeP->am_size = desc->im_size;
793
          addr_modeP->im_disp = 0;
794
        }
795
    }
796
 
797
  return addr_modeP->mode;
798
}
799
 
800
/* Read an optionlist.  */
801
 
802
static void
803
optlist (char *str,                     /* The string to extract options from.  */
804
         struct ns32k_option *optionP,  /* How to search the string.  */
805
         unsigned long *default_map)    /* Default pattern and output.  */
806
{
807
  int i, j, k, strlen1, strlen2;
808
  char *patternP, *strP;
809
 
810
  strlen1 = strlen (str);
811
 
812
  if (strlen1 < 1)
813
    as_fatal (_("Very short instr to option, ie you can't do it on a NULLstr"));
814
 
815
  for (i = 0; optionP[i].pattern != 0; i++)
816
    {
817
      strlen2 = strlen (optionP[i].pattern);
818
 
819
      for (j = 0; j < strlen1; j++)
820
        {
821
          patternP = optionP[i].pattern;
822
          strP = &str[j];
823
 
824
          for (k = 0; k < strlen2; k++)
825
            {
826
              if (*(strP++) != *(patternP++))
827
                break;
828
            }
829
 
830
          if (k == strlen2)
831
            {                   /* match */
832
              *default_map |= optionP[i].or;
833
              *default_map &= optionP[i].and;
834
            }
835
        }
836
    }
837
}
838
 
839
/* Search struct for symbols.
840
   This function is used to get the short integer form of reg names in
841
   the instructions lmr, smr, lpr, spr return true if str is found in
842
   list.  */
843
 
844
static int
845
list_search (char *str,                         /* The string to match.  */
846
             struct ns32k_option *optionP,      /* List to search.  */
847
             unsigned long *default_map)        /* Default pattern and output.  */
848
{
849
  int i;
850
 
851
  for (i = 0; optionP[i].pattern != 0; i++)
852
    {
853
      if (!strncmp (optionP[i].pattern, str, 20))
854
        {
855
          /* Use strncmp to be safe.  */
856
          *default_map |= optionP[i].or;
857
          *default_map &= optionP[i].and;
858
 
859
          return -1;
860
        }
861
    }
862
 
863
  as_bad (_("No such entry in list. (cpu/mmu register)"));
864
  return 0;
865
}
866
 
867
/* Create a bit_fixS in obstack 'notes'.
868
   This struct is used to profile the normal fix. If the bit_fixP is a
869
   valid pointer (not NULL) the bit_fix data will be used to format
870
   the fix.  */
871
 
872
static bit_fixS *
873
bit_fix_new (int size,          /* Length of bitfield.  */
874
             int offset,        /* Bit offset to bitfield.  */
875
             long min,          /* Signextended min for bitfield.  */
876
             long max,          /* Signextended max for bitfield.  */
877
             long add,          /* Add mask, used for huffman prefix.  */
878
             long base_type,    /* 0 or 1, if 1 it's exploded to opcode ptr.  */
879
             long base_adj)
880
{
881
  bit_fixS *bit_fixP;
882
 
883
  bit_fixP = obstack_alloc (&notes, sizeof (bit_fixS));
884
 
885
  bit_fixP->fx_bit_size = size;
886
  bit_fixP->fx_bit_offset = offset;
887
  bit_fixP->fx_bit_base = base_type;
888
  bit_fixP->fx_bit_base_adj = base_adj;
889
  bit_fixP->fx_bit_max = max;
890
  bit_fixP->fx_bit_min = min;
891
  bit_fixP->fx_bit_add = add;
892
 
893
  return bit_fixP;
894
}
895
 
896
/* Convert operands to iif-format and adds bitfields to the opcode.
897
   Operands are parsed in such an order that the opcode is updated from
898
   its most significant bit, that is when the operand need to alter the
899
   opcode.
900
   Be careful not to put to objects in the same iif-slot.  */
901
 
902
static void
903
encode_operand (int argc,
904
                char **argv,
905
                const char *operandsP,
906
                const char *suffixP,
907
                char im_size ATTRIBUTE_UNUSED,
908
                char opcode_bit_ptr)
909
{
910
  int i, j;
911
  char d;
912
  int pcrel, b, loop, pcrel_adjust;
913
  unsigned long tmp;
914
 
915
  for (loop = 0; loop < argc; loop++)
916
    {
917
      /* What operand are we supposed to work on.  */
918
      i = operandsP[loop << 1] - '1';
919
      if (i > 3)
920
        as_fatal (_("Internal consistency error.  check ns32k-opcode.h"));
921
 
922
      pcrel = 0;
923
      pcrel_adjust = 0;
924
      tmp = 0;
925
 
926
      switch ((d = operandsP[(loop << 1) + 1]))
927
        {
928
        case 'f':               /* Operand of sfsr turns out to be a nasty
929
                                   specialcase.  */
930
          opcode_bit_ptr -= 5;
931
        case 'Z':               /* Float not immediate.  */
932
        case 'F':               /* 32 bit float general form.  */
933
        case 'L':               /* 64 bit float.  */
934
        case 'I':               /* Integer not immediate.  */
935
        case 'B':               /* Byte  */
936
        case 'W':               /* Word  */
937
        case 'D':               /* Double-word.  */
938
        case 'A':               /* Double-word  gen-address-form ie no regs
939
                                   allowed.  */
940
          get_addr_mode (argv[i], &addr_modeP);
941
 
942
          if ((addr_modeP.mode == 20) &&
943
             (d == 'I' || d == 'Z' || d == 'A'))
944
            as_fatal (d == 'A'? _("Address of immediate operand"):
945
                        _("Invalid immediate write operand."));
946
 
947
          if (opcode_bit_ptr == desc->opcode_size)
948
            b = 4;
949
          else
950
            b = 6;
951
 
952
          for (j = b; j < (b + 2); j++)
953
            {
954
              if (addr_modeP.disp[j - b])
955
                {
956
                  IIF (j,
957
                       2,
958
                       addr_modeP.disp_suffix[j - b],
959
                       (unsigned long) addr_modeP.disp[j - b],
960
                       0,
961
                       addr_modeP.pcrel,
962
                       iif.instr_size,
963
                       addr_modeP.im_disp,
964
                       IND (BRANCH, BYTE),
965
                       NULL,
966
                       (addr_modeP.scaled_reg ? addr_modeP.scaled_mode
967
                        : addr_modeP.mode),
968
                       0);
969
                }
970
            }
971
 
972
          opcode_bit_ptr -= 5;
973
          iif.iifP[1].object |= ((long) addr_modeP.mode) << opcode_bit_ptr;
974
 
975
          if (addr_modeP.scaled_reg)
976
            {
977
              j = b / 2;
978
              IIF (j, 1, 1, (unsigned long) addr_modeP.index_byte,
979
                   0, 0, 0, 0, 0, NULL, -1, 0);
980
            }
981
          break;
982
 
983
        case 'b':               /* Multiple instruction disp.  */
984
          freeptr++;            /* OVE:this is an useful hack.  */
985
          sprintf (freeptr, "((%s-1)*%d)", argv[i], desc->im_size);
986
          argv[i] = freeptr;
987
          pcrel -= 1;           /* Make pcrel 0 in spite of what case 'p':
988
                                   wants.  */
989
          /* fall thru */
990
        case 'p':               /* Displacement - pc relative addressing.  */
991
          pcrel += 1;
992
          /* fall thru */
993
        case 'd':               /* Displacement.  */
994
          iif.instr_size += suffixP[i] ? suffixP[i] : 4;
995
          IIF (12, 2, suffixP[i], (unsigned long) argv[i], 0,
996
               pcrel, pcrel_adjust, 1, IND (BRANCH, BYTE), NULL, -1, 0);
997
          break;
998
        case 'H':               /* Sequent-hack: the linker wants a bit set
999
                                   when bsr.  */
1000
          pcrel = 1;
1001
          iif.instr_size += suffixP[i] ? suffixP[i] : 4;
1002
          IIF (12, 2, suffixP[i], (unsigned long) argv[i], 0,
1003
               pcrel, pcrel_adjust, 1, IND (BRANCH, BYTE), NULL, -1, 1);
1004
          break;
1005
        case 'q':               /* quick */
1006
          opcode_bit_ptr -= 4;
1007
          IIF (11, 2, 42, (unsigned long) argv[i], 0, 0, 0, 0, 0,
1008
               bit_fix_new (4, opcode_bit_ptr, -8, 7, 0, 1, 0), -1, 0);
1009
          break;
1010
        case 'r':               /* Register number (3 bits).  */
1011
          list_search (argv[i], opt6, &tmp);
1012
          opcode_bit_ptr -= 3;
1013
          iif.iifP[1].object |= tmp << opcode_bit_ptr;
1014
          break;
1015
        case 'O':               /* Setcfg instruction optionslist.  */
1016
          optlist (argv[i], opt3, &tmp);
1017
          opcode_bit_ptr -= 4;
1018
          iif.iifP[1].object |= tmp << 15;
1019
          break;
1020
        case 'C':               /* Cinv instruction optionslist.  */
1021
          optlist (argv[i], opt4, &tmp);
1022
          opcode_bit_ptr -= 4;
1023
          iif.iifP[1].object |= tmp << 15; /* Insert the regtype in opcode.  */
1024
          break;
1025
        case 'S':               /* String instruction options list.  */
1026
          optlist (argv[i], opt5, &tmp);
1027
          opcode_bit_ptr -= 4;
1028
          iif.iifP[1].object |= tmp << 15;
1029
          break;
1030
        case 'u':
1031
        case 'U':               /* Register list.  */
1032
          IIF (10, 1, 1, 0, 0, 0, 0, 0, 0, NULL, -1, 0);
1033
          switch (operandsP[(i << 1) + 1])
1034
            {
1035
            case 'u':           /* Restore, exit.  */
1036
              optlist (argv[i], opt1, &iif.iifP[10].object);
1037
              break;
1038
            case 'U':           /* Save, enter.  */
1039
              optlist (argv[i], opt2, &iif.iifP[10].object);
1040
              break;
1041
            }
1042
          iif.instr_size += 1;
1043
          break;
1044
        case 'M':               /* MMU register.  */
1045
          list_search (argv[i], mmureg, &tmp);
1046
          opcode_bit_ptr -= 4;
1047
          iif.iifP[1].object |= tmp << opcode_bit_ptr;
1048
          break;
1049
        case 'P':               /* CPU register.  */
1050
          list_search (argv[i], cpureg, &tmp);
1051
          opcode_bit_ptr -= 4;
1052
          iif.iifP[1].object |= tmp << opcode_bit_ptr;
1053
          break;
1054
        case 'g':               /* Inss exts.  */
1055
          iif.instr_size += 1;  /* 1 byte is allocated after the opcode.  */
1056
          IIF (10, 2, 1,
1057
               (unsigned long) argv[i], /* i always 2 here.  */
1058
               0, 0, 0, 0, 0,
1059
               bit_fix_new (3, 5, 0, 7, 0, 0, 0), /* A bit_fix is targeted to
1060
                                                     the byte.  */
1061
               -1, 0);
1062
          break;
1063
        case 'G':
1064
          IIF (11, 2, 42,
1065
               (unsigned long) argv[i], /* i always 3 here.  */
1066
               0, 0, 0, 0, 0,
1067
               bit_fix_new (5, 0, 1, 32, -1, 0, -1), -1, 0);
1068
          break;
1069
        case 'i':
1070
          iif.instr_size += 1;
1071
          b = 2 + i;            /* Put the extension byte after opcode.  */
1072
          IIF (b, 2, 1, 0, 0, 0, 0, 0, 0, 0, -1, 0);
1073
          break;
1074
        default:
1075
          as_fatal (_("Bad opcode-table-option, check in file ns32k-opcode.h"));
1076
        }
1077
    }
1078
}
1079
 
1080
/* in:  instruction line
1081
   out: internal structure of instruction
1082
   that has been prepared for direct conversion to fragment(s) and
1083
   fixes in a systematical fashion
1084
   Return-value = recursive_level.  */
1085
/* Build iif of one assembly text line.  */
1086
 
1087
static int
1088
parse (const char *line, int recursive_level)
1089
{
1090
  const char *lineptr;
1091
  char c, suffix_separator;
1092
  int i;
1093
  unsigned int argc;
1094
  int arg_type;
1095
  char sqr, sep;
1096
  char suffix[MAX_ARGS], *argv[MAX_ARGS];       /* No more than 4 operands.  */
1097
 
1098
  if (recursive_level <= 0)
1099
    {
1100
      /* Called from md_assemble.  */
1101
      for (lineptr = line; (*lineptr) != '\0' && (*lineptr) != ' '; lineptr++)
1102
        continue;
1103
 
1104
      c = *lineptr;
1105
      *(char *) lineptr = '\0';
1106
 
1107
      if (!(desc = (struct ns32k_opcode *) hash_find (inst_hash_handle, line)))
1108
        as_fatal (_("No such opcode"));
1109
 
1110
      *(char *) lineptr = c;
1111
    }
1112
  else
1113
    lineptr = line;
1114
 
1115
  argc = 0;
1116
 
1117
  if (*desc->operands)
1118
    {
1119
      if (*lineptr++ != '\0')
1120
        {
1121
          sqr = '[';
1122
          sep = ',';
1123
 
1124
          while (*lineptr != '\0')
1125
            {
1126
              if (desc->operands[argc << 1])
1127
                {
1128
                  suffix[argc] = 0;
1129
                  arg_type = desc->operands[(argc << 1) + 1];
1130
 
1131
                  switch (arg_type)
1132
                    {
1133
                    case 'd':
1134
                    case 'b':
1135
                    case 'p':
1136
                    case 'H':
1137
                      /* The operand is supposed to be a displacement.  */
1138
                      /* Hackwarning: do not forget to update the 4
1139
                         cases above when editing ns32k-opcode.h.  */
1140
                      suffix_separator = ':';
1141
                      break;
1142
                    default:
1143
                      /* If this char occurs we loose.  */
1144
                      suffix_separator = '\255';
1145
                      break;
1146
                    }
1147
 
1148
                  suffix[argc] = 0; /* 0 when no ':' is encountered.  */
1149
                  argv[argc] = freeptr;
1150
                  *freeptr = '\0';
1151
 
1152
                  while ((c = *lineptr) != '\0' && c != sep)
1153
                    {
1154
                      if (c == sqr)
1155
                        {
1156
                          if (sqr == '[')
1157
                            {
1158
                              sqr = ']';
1159
                              sep = '\0';
1160
                            }
1161
                          else
1162
                            {
1163
                              sqr = '[';
1164
                              sep = ',';
1165
                            }
1166
                        }
1167
 
1168
                      if (c == suffix_separator)
1169
                        {
1170
                          /* ':' - label/suffix separator.  */
1171
                          switch (lineptr[1])
1172
                            {
1173
                            case 'b':
1174
                              suffix[argc] = 1;
1175
                              break;
1176
                            case 'w':
1177
                              suffix[argc] = 2;
1178
                              break;
1179
                            case 'd':
1180
                              suffix[argc] = 4;
1181
                              break;
1182
                            default:
1183
                              as_warn (_("Bad suffix, defaulting to d"));
1184
                              suffix[argc] = 4;
1185
                              if (lineptr[1] == '\0' || lineptr[1] == sep)
1186
                                {
1187
                                  lineptr += 1;
1188
                                  continue;
1189
                                }
1190
                              break;
1191
                            }
1192
 
1193
                          lineptr += 2;
1194
                          continue;
1195
                        }
1196
 
1197
                      *freeptr++ = c;
1198
                      lineptr++;
1199
                    }
1200
 
1201
                  *freeptr++ = '\0';
1202
                  argc += 1;
1203
 
1204
                  if (*lineptr == '\0')
1205
                    continue;
1206
 
1207
                  lineptr += 1;
1208
                }
1209
              else
1210
                as_fatal (_("Too many operands passed to instruction"));
1211
            }
1212
        }
1213
    }
1214
 
1215
  if (argc != strlen (desc->operands) / 2)
1216
    {
1217
      if (strlen (desc->default_args))
1218
        {
1219
          /* We can apply default, don't goof.  */
1220
          if (parse (desc->default_args, 1) != 1)
1221
            /* Check error in default.  */
1222
            as_fatal (_("Wrong numbers of operands in default, check ns32k-opcodes.h"));
1223
        }
1224
      else
1225
        as_fatal (_("Wrong number of operands"));
1226
    }
1227
 
1228
  for (i = 0; i < IIF_ENTRIES; i++)
1229
    /* Mark all entries as void.  */
1230
    iif.iifP[i].type = 0;
1231
 
1232
  /* Build opcode iif-entry.  */
1233
  iif.instr_size = desc->opcode_size / 8;
1234
  IIF (1, 1, iif.instr_size, desc->opcode_seed, 0, 0, 0, 0, 0, 0, -1, 0);
1235
 
1236
  /* This call encodes operands to iif format.  */
1237
  if (argc)
1238
    encode_operand (argc, argv, &desc->operands[0],
1239
                    &suffix[0], desc->im_size, desc->opcode_size);
1240
 
1241
  return recursive_level;
1242
}
1243
 
1244
/* This functionality should really be in the bfd library.  */
1245
 
1246
static bfd_reloc_code_real_type
1247
reloc (int size, int pcrel, int type)
1248
{
1249
  int length, index;
1250
  bfd_reloc_code_real_type relocs[] =
1251
  {
1252
    BFD_RELOC_NS32K_IMM_8,
1253
    BFD_RELOC_NS32K_IMM_16,
1254
    BFD_RELOC_NS32K_IMM_32,
1255
    BFD_RELOC_NS32K_IMM_8_PCREL,
1256
    BFD_RELOC_NS32K_IMM_16_PCREL,
1257
    BFD_RELOC_NS32K_IMM_32_PCREL,
1258
 
1259
    /* ns32k displacements.  */
1260
    BFD_RELOC_NS32K_DISP_8,
1261
    BFD_RELOC_NS32K_DISP_16,
1262
    BFD_RELOC_NS32K_DISP_32,
1263
    BFD_RELOC_NS32K_DISP_8_PCREL,
1264
    BFD_RELOC_NS32K_DISP_16_PCREL,
1265
    BFD_RELOC_NS32K_DISP_32_PCREL,
1266
 
1267
    /* Normal 2's complement.  */
1268
    BFD_RELOC_8,
1269
    BFD_RELOC_16,
1270
    BFD_RELOC_32,
1271
    BFD_RELOC_8_PCREL,
1272
    BFD_RELOC_16_PCREL,
1273
    BFD_RELOC_32_PCREL
1274
  };
1275
 
1276
  switch (size)
1277
    {
1278
    case 1:
1279
      length = 0;
1280
      break;
1281
    case 2:
1282
      length = 1;
1283
      break;
1284
    case 4:
1285
      length = 2;
1286
      break;
1287
    default:
1288
      length = -1;
1289
      break;
1290
    }
1291
 
1292
  index = length + 3 * pcrel + 6 * type;
1293
 
1294
  if (index >= 0 && (unsigned int) index < sizeof (relocs) / sizeof (relocs[0]))
1295
    return relocs[index];
1296
 
1297
  if (pcrel)
1298
    as_bad (_("Can not do %d byte pc-relative relocation for storage type %d"),
1299
            size, type);
1300
  else
1301
    as_bad (_("Can not do %d byte relocation for storage type %d"),
1302
            size, type);
1303
 
1304
  return BFD_RELOC_NONE;
1305
 
1306
}
1307
 
1308
static void
1309
fix_new_ns32k (fragS *frag,             /* Which frag? */
1310
               int where,               /* Where in that frag? */
1311
               int size,                /* 1, 2  or 4 usually.  */
1312
               symbolS *add_symbol,     /* X_add_symbol.  */
1313
               long offset,             /* X_add_number.  */
1314
               int pcrel,               /* True if PC-relative relocation.  */
1315
               char im_disp,            /* True if the value to write is a
1316
                                           displacement.  */
1317
               bit_fixS *bit_fixP,      /* Pointer at struct of bit_fix's, ignored if
1318
                                           NULL.  */
1319
               char bsr,                /* Sequent-linker-hack: 1 when relocobject is
1320
                                           a bsr.  */
1321
               fragS *opcode_frag,
1322
               unsigned int opcode_offset)
1323
{
1324
  fixS *fixP = fix_new (frag, where, size, add_symbol,
1325
                        offset, pcrel,
1326
                        bit_fixP ? NO_RELOC : reloc (size, pcrel, im_disp)
1327
                        );
1328
 
1329
  fix_opcode_frag (fixP) = opcode_frag;
1330
  fix_opcode_offset (fixP) = opcode_offset;
1331
  fix_im_disp (fixP) = im_disp;
1332
  fix_bsr (fixP) = bsr;
1333
  fix_bit_fixP (fixP) = bit_fixP;
1334
  /* We have a MD overflow check for displacements.  */
1335
  fixP->fx_no_overflow = (im_disp != 0);
1336
}
1337
 
1338
static void
1339
fix_new_ns32k_exp (fragS *frag,         /* Which frag? */
1340
                   int where,           /* Where in that frag? */
1341
                   int size,            /* 1, 2  or 4 usually.  */
1342
                   expressionS *exp,    /* Expression.  */
1343
                   int pcrel,           /* True if PC-relative relocation.  */
1344
                   char im_disp,        /* True if the value to write is a
1345
                                           displacement.  */
1346
                   bit_fixS *bit_fixP,  /* Pointer at struct of bit_fix's, ignored if
1347
                                           NULL.  */
1348
                   char bsr,            /* Sequent-linker-hack: 1 when relocobject is
1349
                                           a bsr.  */
1350
                   fragS *opcode_frag,
1351
                   unsigned int opcode_offset)
1352
{
1353
  fixS *fixP = fix_new_exp (frag, where, size, exp, pcrel,
1354
                            bit_fixP ? NO_RELOC : reloc (size, pcrel, im_disp)
1355
                            );
1356
 
1357
  fix_opcode_frag (fixP) = opcode_frag;
1358
  fix_opcode_offset (fixP) = opcode_offset;
1359
  fix_im_disp (fixP) = im_disp;
1360
  fix_bsr (fixP) = bsr;
1361
  fix_bit_fixP (fixP) = bit_fixP;
1362
  /* We have a MD overflow check for displacements.  */
1363
  fixP->fx_no_overflow = (im_disp != 0);
1364
}
1365
 
1366
/* Convert number to chars in correct order.  */
1367
 
1368
void
1369
md_number_to_chars (char *buf, valueT value, int nbytes)
1370
{
1371
  number_to_chars_littleendian (buf, value, nbytes);
1372
}
1373
 
1374
/* This is a variant of md_numbers_to_chars. The reason for its'
1375
   existence is the fact that ns32k uses Huffman coded
1376
   displacements. This implies that the bit order is reversed in
1377
   displacements and that they are prefixed with a size-tag.
1378
 
1379
   binary: msb -> lsb
1380
   0xxxxxxx                             byte
1381
   10xxxxxx xxxxxxxx                    word
1382
   11xxxxxx xxxxxxxx xxxxxxxx xxxxxxxx  double word
1383
 
1384
   This must be taken care of and we do it here!  */
1385
 
1386
static void
1387
md_number_to_disp (char *buf, long val, int n)
1388
{
1389
  switch (n)
1390
    {
1391
    case 1:
1392
      if (val < -64 || val > 63)
1393
        as_bad (_("value of %ld out of byte displacement range."), val);
1394
      val &= 0x7f;
1395
#ifdef SHOW_NUM
1396
      printf ("%x ", val & 0xff);
1397
#endif
1398
      *buf++ = val;
1399
      break;
1400
 
1401
    case 2:
1402
      if (val < -8192 || val > 8191)
1403
        as_bad (_("value of %ld out of word displacement range."), val);
1404
      val &= 0x3fff;
1405
      val |= 0x8000;
1406
#ifdef SHOW_NUM
1407
      printf ("%x ", val >> 8 & 0xff);
1408
#endif
1409
      *buf++ = (val >> 8);
1410
#ifdef SHOW_NUM
1411
      printf ("%x ", val & 0xff);
1412
#endif
1413
      *buf++ = val;
1414
      break;
1415
 
1416
    case 4:
1417
      if (val < -0x20000000 || val >= 0x20000000)
1418
        as_bad (_("value of %ld out of double word displacement range."), val);
1419
      val |= 0xc0000000;
1420
#ifdef SHOW_NUM
1421
      printf ("%x ", val >> 24 & 0xff);
1422
#endif
1423
      *buf++ = (val >> 24);
1424
#ifdef SHOW_NUM
1425
      printf ("%x ", val >> 16 & 0xff);
1426
#endif
1427
      *buf++ = (val >> 16);
1428
#ifdef SHOW_NUM
1429
      printf ("%x ", val >> 8 & 0xff);
1430
#endif
1431
      *buf++ = (val >> 8);
1432
#ifdef SHOW_NUM
1433
      printf ("%x ", val & 0xff);
1434
#endif
1435
      *buf++ = val;
1436
      break;
1437
 
1438
    default:
1439
      as_fatal (_("Internal logic error.  line %d, file \"%s\""),
1440
                __LINE__, __FILE__);
1441
    }
1442
}
1443
 
1444
static void
1445
md_number_to_imm (char *buf, long val, int n)
1446
{
1447
  switch (n)
1448
    {
1449
    case 1:
1450
#ifdef SHOW_NUM
1451
      printf ("%x ", val & 0xff);
1452
#endif
1453
      *buf++ = val;
1454
      break;
1455
 
1456
    case 2:
1457
#ifdef SHOW_NUM
1458
      printf ("%x ", val >> 8 & 0xff);
1459
#endif
1460
      *buf++ = (val >> 8);
1461
#ifdef SHOW_NUM
1462
      printf ("%x ", val & 0xff);
1463
#endif
1464
      *buf++ = val;
1465
      break;
1466
 
1467
    case 4:
1468
#ifdef SHOW_NUM
1469
      printf ("%x ", val >> 24 & 0xff);
1470
#endif
1471
      *buf++ = (val >> 24);
1472
#ifdef SHOW_NUM
1473
      printf ("%x ", val >> 16 & 0xff);
1474
#endif
1475
      *buf++ = (val >> 16);
1476
#ifdef SHOW_NUM
1477
      printf ("%x ", val >> 8 & 0xff);
1478
#endif
1479
      *buf++ = (val >> 8);
1480
#ifdef SHOW_NUM
1481
      printf ("%x ", val & 0xff);
1482
#endif
1483
      *buf++ = val;
1484
      break;
1485
 
1486
    default:
1487
      as_fatal (_("Internal logic error. line %d, file \"%s\""),
1488
                __LINE__, __FILE__);
1489
    }
1490
}
1491
 
1492
/* Fast bitfiddling support.  */
1493
/* Mask used to zero bitfield before oring in the true field.  */
1494
 
1495
static unsigned long l_mask[] =
1496
{
1497
  0xffffffff, 0xfffffffe, 0xfffffffc, 0xfffffff8,
1498
  0xfffffff0, 0xffffffe0, 0xffffffc0, 0xffffff80,
1499
  0xffffff00, 0xfffffe00, 0xfffffc00, 0xfffff800,
1500
  0xfffff000, 0xffffe000, 0xffffc000, 0xffff8000,
1501
  0xffff0000, 0xfffe0000, 0xfffc0000, 0xfff80000,
1502
  0xfff00000, 0xffe00000, 0xffc00000, 0xff800000,
1503
  0xff000000, 0xfe000000, 0xfc000000, 0xf8000000,
1504
  0xf0000000, 0xe0000000, 0xc0000000, 0x80000000,
1505
};
1506
static unsigned long r_mask[] =
1507
{
1508
  0x00000000, 0x00000001, 0x00000003, 0x00000007,
1509
  0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
1510
  0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
1511
  0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
1512
  0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
1513
  0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
1514
  0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
1515
  0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
1516
};
1517
#define MASK_BITS 31
1518
/* Insert bitfield described by field_ptr and val at buf
1519
   This routine is written for modification of the first 4 bytes pointed
1520
   to by buf, to yield speed.
1521
   The ifdef stuff is for selection between a ns32k-dependent routine
1522
   and a general version. (My advice: use the general version!).  */
1523
 
1524
static void
1525
md_number_to_field (char *buf, long val, bit_fixS *field_ptr)
1526
{
1527
  unsigned long object;
1528
  unsigned long mask;
1529
  /* Define ENDIAN on a ns32k machine.  */
1530
#ifdef ENDIAN
1531
  unsigned long *mem_ptr;
1532
#else
1533
  char *mem_ptr;
1534
#endif
1535
 
1536
  if (field_ptr->fx_bit_min <= val && val <= field_ptr->fx_bit_max)
1537
    {
1538
#ifdef ENDIAN
1539
      if (field_ptr->fx_bit_base)
1540
        /* Override buf.  */
1541
        mem_ptr = (unsigned long *) field_ptr->fx_bit_base;
1542
      else
1543
        mem_ptr = (unsigned long *) buf;
1544
 
1545
      mem_ptr = ((unsigned long *)
1546
                 ((char *) mem_ptr + field_ptr->fx_bit_base_adj));
1547
#else
1548
      if (field_ptr->fx_bit_base)
1549
        mem_ptr = (char *) field_ptr->fx_bit_base;
1550
      else
1551
        mem_ptr = buf;
1552
 
1553
      mem_ptr += field_ptr->fx_bit_base_adj;
1554
#endif
1555
#ifdef ENDIAN
1556
      /* We have a nice ns32k machine with lowbyte at low-physical mem.  */
1557
      object = *mem_ptr;        /* get some bytes */
1558
#else /* OVE Goof! the machine is a m68k or dito.  */
1559
      /* That takes more byte fiddling.  */
1560
      object = 0;
1561
      object |= mem_ptr[3] & 0xff;
1562
      object <<= 8;
1563
      object |= mem_ptr[2] & 0xff;
1564
      object <<= 8;
1565
      object |= mem_ptr[1] & 0xff;
1566
      object <<= 8;
1567
      object |= mem_ptr[0] & 0xff;
1568
#endif
1569
      mask = 0;
1570
      mask |= (r_mask[field_ptr->fx_bit_offset]);
1571
      mask |= (l_mask[field_ptr->fx_bit_offset + field_ptr->fx_bit_size]);
1572
      object &= mask;
1573
      val += field_ptr->fx_bit_add;
1574
      object |= ((val << field_ptr->fx_bit_offset) & (mask ^ 0xffffffff));
1575
#ifdef ENDIAN
1576
      *mem_ptr = object;
1577
#else
1578
      mem_ptr[0] = (char) object;
1579
      object >>= 8;
1580
      mem_ptr[1] = (char) object;
1581
      object >>= 8;
1582
      mem_ptr[2] = (char) object;
1583
      object >>= 8;
1584
      mem_ptr[3] = (char) object;
1585
#endif
1586
    }
1587
  else
1588
    as_bad (_("Bit field out of range"));
1589
}
1590
 
1591
/* Convert iif to fragments.  From this point we start to dribble with
1592
   functions in other files than this one.(Except hash.c) So, if it's
1593
   possible to make an iif for an other CPU, you don't need to know
1594
   what frags, relax, obstacks, etc is in order to port this
1595
   assembler. You only need to know if it's possible to reduce your
1596
   cpu-instruction to iif-format (takes some work) and adopt the other
1597
   md_? parts according to given instructions Note that iif was
1598
   invented for the clean ns32k`s architecture.  */
1599
 
1600
/* GAS for the ns32k has a problem. PC relative displacements are
1601
   relative to the address of the opcode, not the address of the
1602
   operand. We used to keep track of the offset between the operand
1603
   and the opcode in pcrel_adjust for each frag and each fix. However,
1604
   we get into trouble where there are two or more pc-relative
1605
   operands and the size of the first one can't be determined. Then in
1606
   the relax phase, the size of the first operand will change and
1607
   pcrel_adjust will no longer be correct.  The current solution is
1608
   keep a pointer to the frag with the opcode in it and the offset in
1609
   that frag for each frag and each fix. Then, when needed, we can
1610
   always figure out how far it is between the opcode and the pcrel
1611
   object.  See also md_pcrel_adjust and md_fix_pcrel_adjust.  For
1612
   objects not part of an instruction, the pointer to the opcode frag
1613
   is always zero.  */
1614
 
1615
static void
1616
convert_iif (void)
1617
{
1618
  int i;
1619
  bit_fixS *j;
1620
  fragS *inst_frag;
1621
  unsigned int inst_offset;
1622
  char *inst_opcode;
1623
  char *memP;
1624
  int l;
1625
  int k;
1626
  char type;
1627
  char size = 0;
1628
 
1629
  frag_grow (iif.instr_size);   /* This is important.  */
1630
  memP = frag_more (0);
1631
  inst_opcode = memP;
1632
  inst_offset = (memP - frag_now->fr_literal);
1633
  inst_frag = frag_now;
1634
 
1635
  for (i = 0; i < IIF_ENTRIES; i++)
1636
    {
1637
      if ((type = iif.iifP[i].type))
1638
        {
1639
          /* The object exist, so handle it.  */
1640
          switch (size = iif.iifP[i].size)
1641
            {
1642
            case 42:
1643
              size = 0;
1644
              /* It's a bitfix that operates on an existing object.  */
1645
              if (iif.iifP[i].bit_fixP->fx_bit_base)
1646
                /* Expand fx_bit_base to point at opcode.  */
1647
                iif.iifP[i].bit_fixP->fx_bit_base = (long) inst_opcode;
1648
              /* Fall through.  */
1649
 
1650
            case 8:             /* bignum or doublefloat.  */
1651
            case 1:
1652
            case 2:
1653
            case 3:
1654
            case 4:
1655
              /* The final size in objectmemory is known.  */
1656
              memP = frag_more (size);
1657
              j = iif.iifP[i].bit_fixP;
1658
 
1659
              switch (type)
1660
                {
1661
                case 1: /* The object is pure binary.  */
1662
                  if (j)
1663
                    md_number_to_field (memP, exprP.X_add_number, j);
1664
 
1665
                  else if (iif.iifP[i].pcrel)
1666
                    fix_new_ns32k (frag_now,
1667
                                   (long) (memP - frag_now->fr_literal),
1668
                                   size,
1669
                                   0,
1670
                                   iif.iifP[i].object,
1671
                                   iif.iifP[i].pcrel,
1672
                                   iif.iifP[i].im_disp,
1673
                                   0,
1674
                                   iif.iifP[i].bsr,     /* Sequent hack.  */
1675
                                   inst_frag, inst_offset);
1676
                  else
1677
                    {
1678
                      /* Good, just put them bytes out.  */
1679
                      switch (iif.iifP[i].im_disp)
1680
                        {
1681
                        case 0:
1682
                          md_number_to_chars (memP, iif.iifP[i].object, size);
1683
                          break;
1684
                        case 1:
1685
                          md_number_to_disp (memP, iif.iifP[i].object, size);
1686
                          break;
1687
                        default:
1688
                          as_fatal (_("iif convert internal pcrel/binary"));
1689
                        }
1690
                    }
1691
                  break;
1692
 
1693
                case 2:
1694
                  /* The object is a pointer at an expression, so
1695
                     unpack it, note that bignums may result from the
1696
                     expression.  */
1697
                  evaluate_expr (&exprP, (char *) iif.iifP[i].object);
1698
                  if (exprP.X_op == O_big || size == 8)
1699
                    {
1700
                      if ((k = exprP.X_add_number) > 0)
1701
                        {
1702
                          /* We have a bignum ie a quad. This can only
1703
                             happens in a long suffixed instruction.  */
1704
                          if (k * 2 > size)
1705
                            as_bad (_("Bignum too big for long"));
1706
 
1707
                          if (k == 3)
1708
                            memP += 2;
1709
 
1710
                          for (l = 0; k > 0; k--, l += 2)
1711
                            md_number_to_chars (memP + l,
1712
                                                generic_bignum[l >> 1],
1713
                                                sizeof (LITTLENUM_TYPE));
1714
                        }
1715
                      else
1716
                        {
1717
                          /* flonum.  */
1718
                          LITTLENUM_TYPE words[4];
1719
 
1720
                          switch (size)
1721
                            {
1722
                            case 4:
1723
                              gen_to_words (words, 2, 8);
1724
                              md_number_to_imm (memP, (long) words[0],
1725
                                                sizeof (LITTLENUM_TYPE));
1726
                              md_number_to_imm (memP + sizeof (LITTLENUM_TYPE),
1727
                                                (long) words[1],
1728
                                                sizeof (LITTLENUM_TYPE));
1729
                              break;
1730
                            case 8:
1731
                              gen_to_words (words, 4, 11);
1732
                              md_number_to_imm (memP, (long) words[0],
1733
                                                sizeof (LITTLENUM_TYPE));
1734
                              md_number_to_imm (memP + sizeof (LITTLENUM_TYPE),
1735
                                                (long) words[1],
1736
                                                sizeof (LITTLENUM_TYPE));
1737
                              md_number_to_imm ((memP + 2
1738
                                                 * sizeof (LITTLENUM_TYPE)),
1739
                                                (long) words[2],
1740
                                                sizeof (LITTLENUM_TYPE));
1741
                              md_number_to_imm ((memP + 3
1742
                                                 * sizeof (LITTLENUM_TYPE)),
1743
                                                (long) words[3],
1744
                                                sizeof (LITTLENUM_TYPE));
1745
                              break;
1746
                            }
1747
                        }
1748
                      break;
1749
                    }
1750
                  if (exprP.X_add_symbol ||
1751
                      exprP.X_op_symbol ||
1752
                      iif.iifP[i].pcrel)
1753
                    {
1754
                      /* The expression was undefined due to an
1755
                         undefined label. Create a fix so we can fix
1756
                         the object later.  */
1757
                      exprP.X_add_number += iif.iifP[i].object_adjust;
1758
                      fix_new_ns32k_exp (frag_now,
1759
                                         (long) (memP - frag_now->fr_literal),
1760
                                         size,
1761
                                         &exprP,
1762
                                         iif.iifP[i].pcrel,
1763
                                         iif.iifP[i].im_disp,
1764
                                         j,
1765
                                         iif.iifP[i].bsr,
1766
                                         inst_frag, inst_offset);
1767
                    }
1768
                  else if (j)
1769
                    md_number_to_field (memP, exprP.X_add_number, j);
1770
                  else
1771
                    {
1772
                      /* Good, just put them bytes out.  */
1773
                      switch (iif.iifP[i].im_disp)
1774
                        {
1775
                        case 0:
1776
                          md_number_to_imm (memP, exprP.X_add_number, size);
1777
                          break;
1778
                        case 1:
1779
                          md_number_to_disp (memP, exprP.X_add_number, size);
1780
                          break;
1781
                        default:
1782
                          as_fatal (_("iif convert internal pcrel/pointer"));
1783
                        }
1784
                    }
1785
                  break;
1786
                default:
1787
                  as_fatal (_("Internal logic error in iif.iifP[n].type"));
1788
                }
1789
              break;
1790
 
1791
            case 0:
1792
              /* Too bad, the object may be undefined as far as its
1793
                 final nsize in object memory is concerned.  The size
1794
                 of the object in objectmemory is not explicitly
1795
                 given.  If the object is defined its length can be
1796
                 determined and a fix can replace the frag.  */
1797
              {
1798
                evaluate_expr (&exprP, (char *) iif.iifP[i].object);
1799
 
1800
                if ((exprP.X_add_symbol || exprP.X_op_symbol) &&
1801
                    !iif.iifP[i].pcrel)
1802
                  {
1803
                    /* Size is unknown until link time so have to default.  */
1804
                    size = default_disp_size; /* Normally 4 bytes.  */
1805
                    memP = frag_more (size);
1806
                    fix_new_ns32k_exp (frag_now,
1807
                                       (long) (memP - frag_now->fr_literal),
1808
                                       size,
1809
                                       &exprP,
1810
                                       0, /* never iif.iifP[i].pcrel, */
1811
                                       1, /* always iif.iifP[i].im_disp */
1812
                                       (bit_fixS *) 0, 0,
1813
                                       inst_frag,
1814
                                       inst_offset);
1815
                    break;              /* Exit this absolute hack.  */
1816
                  }
1817
 
1818
                if (exprP.X_add_symbol || exprP.X_op_symbol)
1819
                  {
1820
                    /* Frag it.  */
1821
                    if (exprP.X_op_symbol)
1822
                      /* We cant relax this case.  */
1823
                      as_fatal (_("Can't relax difference"));
1824
                    else
1825
                      {
1826
                        /* Size is not important.  This gets fixed by
1827
                           relax, but we assume 0 in what follows.  */
1828
                        memP = frag_more (4); /* Max size.  */
1829
                        size = 0;
1830
 
1831
                        {
1832
                          fragS *old_frag = frag_now;
1833
                          frag_variant (rs_machine_dependent,
1834
                                        4, /* Max size.  */
1835
                                        0, /* Size.  */
1836
                                        IND (BRANCH, UNDEF), /* Expecting
1837
                                                                the worst.  */
1838
                                        exprP.X_add_symbol,
1839
                                        exprP.X_add_number,
1840
                                        inst_opcode);
1841
                          frag_opcode_frag (old_frag) = inst_frag;
1842
                          frag_opcode_offset (old_frag) = inst_offset;
1843
                          frag_bsr (old_frag) = iif.iifP[i].bsr;
1844
                        }
1845
                      }
1846
                  }
1847
                else
1848
                  {
1849
                    /* This duplicates code in md_number_to_disp.  */
1850
                    if (-64 <= exprP.X_add_number && exprP.X_add_number <= 63)
1851
                      size = 1;
1852
                    else
1853
                      {
1854
                        if (-8192 <= exprP.X_add_number
1855
                            && exprP.X_add_number <= 8191)
1856
                          size = 2;
1857
                        else
1858
                          {
1859
                            if (-0x20000000 <= exprP.X_add_number
1860
                                && exprP.X_add_number<=0x1fffffff)
1861
                              size = 4;
1862
                            else
1863
                              {
1864
                                as_bad (_("Displacement too large for :d"));
1865
                                size = 4;
1866
                              }
1867
                          }
1868
                      }
1869
 
1870
                    memP = frag_more (size);
1871
                    md_number_to_disp (memP, exprP.X_add_number, size);
1872
                  }
1873
              }
1874
              break;
1875
 
1876
            default:
1877
              as_fatal (_("Internal logic error in iif.iifP[].type"));
1878
            }
1879
        }
1880
    }
1881
}
1882
 
1883
void
1884
md_assemble (char *line)
1885
{
1886
  freeptr = freeptr_static;
1887
  parse (line, 0);               /* Explode line to more fix form in iif.  */
1888
  convert_iif ();               /* Convert iif to frags, fix's etc.  */
1889
#ifdef SHOW_NUM
1890
  printf (" \t\t\t%s\n", line);
1891
#endif
1892
}
1893
 
1894
void
1895
md_begin (void)
1896
{
1897
  /* Build a hashtable of the instructions.  */
1898
  const struct ns32k_opcode *ptr;
1899
  const char *stat;
1900
  const struct ns32k_opcode *endop;
1901
 
1902
  inst_hash_handle = hash_new ();
1903
 
1904
  endop = ns32k_opcodes + sizeof (ns32k_opcodes) / sizeof (ns32k_opcodes[0]);
1905
  for (ptr = ns32k_opcodes; ptr < endop; ptr++)
1906
    {
1907
      if ((stat = hash_insert (inst_hash_handle, ptr->name, (char *) ptr)))
1908
        /* Fatal.  */
1909
        as_fatal (_("Can't hash %s: %s"), ptr->name, stat);
1910
    }
1911
 
1912
  /* Some private space please!  */
1913
  freeptr_static = (char *) malloc (PRIVATE_SIZE);
1914
}
1915
 
1916
/* Turn the string pointed to by litP into a floating point constant
1917
   of type TYPE, and emit the appropriate bytes.  The number of
1918
   LITTLENUMS emitted is stored in *SIZEP.  An error message is
1919
   returned, or NULL on OK.  */
1920
 
1921
char *
1922
md_atof (int type, char *litP, int *sizeP)
1923
{
1924
  return ieee_md_atof (type, litP, sizeP, FALSE);
1925
}
1926
 
1927
int
1928
md_pcrel_adjust (fragS *fragP)
1929
{
1930
  fragS *opcode_frag;
1931
  addressT opcode_address;
1932
  unsigned int offset;
1933
 
1934
  opcode_frag = frag_opcode_frag (fragP);
1935
  if (opcode_frag == 0)
1936
    return 0;
1937
 
1938
  offset = frag_opcode_offset (fragP);
1939
  opcode_address = offset + opcode_frag->fr_address;
1940
 
1941
  return fragP->fr_address + fragP->fr_fix - opcode_address;
1942
}
1943
 
1944
static int
1945
md_fix_pcrel_adjust (fixS *fixP)
1946
{
1947
  fragS *opcode_frag;
1948
  addressT opcode_address;
1949
  unsigned int offset;
1950
 
1951
  opcode_frag = fix_opcode_frag (fixP);
1952
  if (opcode_frag == 0)
1953
    return 0;
1954
 
1955
  offset = fix_opcode_offset (fixP);
1956
  opcode_address = offset + opcode_frag->fr_address;
1957
 
1958
  return fixP->fx_where + fixP->fx_frag->fr_address - opcode_address;
1959
}
1960
 
1961
/* Apply a fixS (fixup of an instruction or data that we didn't have
1962
   enough info to complete immediately) to the data in a frag.
1963
 
1964
   On the ns32k, everything is in a different format, so we have broken
1965
   out separate functions for each kind of thing we could be fixing.
1966
   They all get called from here.  */
1967
 
1968
void
1969
md_apply_fix (fixS *fixP, valueT * valP, segT seg ATTRIBUTE_UNUSED)
1970
{
1971
  long val = * (long *) valP;
1972
  char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
1973
 
1974
  if (fix_bit_fixP (fixP))
1975
    /* Bitfields to fix, sigh.  */
1976
    md_number_to_field (buf, val, fix_bit_fixP (fixP));
1977
  else switch (fix_im_disp (fixP))
1978
    {
1979
    case 0:
1980
      /* Immediate field.  */
1981
      md_number_to_imm (buf, val, fixP->fx_size);
1982
      break;
1983
 
1984
    case 1:
1985
      /* Displacement field.  */
1986
      /* Calculate offset.  */
1987
      md_number_to_disp (buf,
1988
                         (fixP->fx_pcrel ? val + md_fix_pcrel_adjust (fixP)
1989
                          : val), fixP->fx_size);
1990
      break;
1991
 
1992
    case 2:
1993
      /* Pointer in a data object.  */
1994
      md_number_to_chars (buf, val, fixP->fx_size);
1995
      break;
1996
    }
1997
 
1998
  if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
1999
    fixP->fx_done = 1;
2000
}
2001
 
2002
/* Convert a relaxed displacement to ditto in final output.  */
2003
 
2004
void
2005
md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
2006
                 segT sec ATTRIBUTE_UNUSED,
2007
                 fragS *fragP)
2008
{
2009
  long disp;
2010
  long ext = 0;
2011
  /* Address in gas core of the place to store the displacement.  */
2012
  char *buffer_address = fragP->fr_fix + fragP->fr_literal;
2013
  /* Address in object code of the displacement.  */
2014
  int object_address;
2015
 
2016
  switch (fragP->fr_subtype)
2017
    {
2018
    case IND (BRANCH, BYTE):
2019
      ext = 1;
2020
      break;
2021
    case IND (BRANCH, WORD):
2022
      ext = 2;
2023
      break;
2024
    case IND (BRANCH, DOUBLE):
2025
      ext = 4;
2026
      break;
2027
    }
2028
 
2029
  if (ext == 0)
2030
    return;
2031
 
2032
  know (fragP->fr_symbol);
2033
 
2034
  object_address = fragP->fr_fix + fragP->fr_address;
2035
 
2036
  /* The displacement of the address, from current location.  */
2037
  disp = (S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset) - object_address;
2038
  disp += md_pcrel_adjust (fragP);
2039
 
2040
  md_number_to_disp (buffer_address, (long) disp, (int) ext);
2041
  fragP->fr_fix += ext;
2042
}
2043
 
2044
/* This function returns the estimated size a variable object will occupy,
2045
   one can say that we tries to guess the size of the objects before we
2046
   actually know it.  */
2047
 
2048
int
2049
md_estimate_size_before_relax (fragS *fragP, segT segment)
2050
{
2051
  if (fragP->fr_subtype == IND (BRANCH, UNDEF))
2052
    {
2053
      if (S_GET_SEGMENT (fragP->fr_symbol) != segment)
2054
        {
2055
          /* We don't relax symbols defined in another segment.  The
2056
             thing to do is to assume the object will occupy 4 bytes.  */
2057
          fix_new_ns32k (fragP,
2058
                         (int) (fragP->fr_fix),
2059
                         4,
2060
                         fragP->fr_symbol,
2061
                         fragP->fr_offset,
2062
                         1,
2063
                         1,
2064
                         0,
2065
                         frag_bsr(fragP), /* Sequent hack.  */
2066
                         frag_opcode_frag (fragP),
2067
                         frag_opcode_offset (fragP));
2068
          fragP->fr_fix += 4;
2069
          frag_wane (fragP);
2070
          return 4;
2071
        }
2072
 
2073
      /* Relaxable case.  Set up the initial guess for the variable
2074
         part of the frag.  */
2075
      fragP->fr_subtype = IND (BRANCH, BYTE);
2076
    }
2077
 
2078
  if (fragP->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))
2079
    abort ();
2080
 
2081
  /* Return the size of the variable part of the frag.  */
2082
  return md_relax_table[fragP->fr_subtype].rlx_length;
2083
}
2084
 
2085
int md_short_jump_size = 3;
2086
int md_long_jump_size = 5;
2087
 
2088
void
2089
md_create_short_jump (char *ptr,
2090
                      addressT from_addr,
2091
                      addressT to_addr,
2092
                      fragS *frag ATTRIBUTE_UNUSED,
2093
                      symbolS *to_symbol ATTRIBUTE_UNUSED)
2094
{
2095
  valueT offset;
2096
 
2097
  offset = to_addr - from_addr;
2098
  md_number_to_chars (ptr, (valueT) 0xEA, 1);
2099
  md_number_to_disp (ptr + 1, (valueT) offset, 2);
2100
}
2101
 
2102
void
2103
md_create_long_jump (char *ptr,
2104
                     addressT from_addr,
2105
                     addressT to_addr,
2106
                     fragS *frag ATTRIBUTE_UNUSED,
2107
                     symbolS *to_symbol ATTRIBUTE_UNUSED)
2108
{
2109
  valueT offset;
2110
 
2111
  offset = to_addr - from_addr;
2112
  md_number_to_chars (ptr, (valueT) 0xEA, 1);
2113
  md_number_to_disp (ptr + 1, (valueT) offset, 4);
2114
}
2115
 
2116
const char *md_shortopts = "m:";
2117
 
2118
struct option md_longopts[] =
2119
{
2120
#define OPTION_DISP_SIZE (OPTION_MD_BASE)
2121
  {"disp-size-default", required_argument , NULL, OPTION_DISP_SIZE},
2122
  {NULL, no_argument, NULL, 0}
2123
};
2124
 
2125
size_t md_longopts_size = sizeof (md_longopts);
2126
 
2127
int
2128
md_parse_option (int c, char *arg)
2129
{
2130
  switch (c)
2131
    {
2132
    case 'm':
2133
      if (!strcmp (arg, "32032"))
2134
        {
2135
          cpureg = cpureg_032;
2136
          mmureg = mmureg_032;
2137
        }
2138
      else if (!strcmp (arg, "32532"))
2139
        {
2140
          cpureg = cpureg_532;
2141
          mmureg = mmureg_532;
2142
        }
2143
      else
2144
        {
2145
          as_warn (_("invalid architecture option -m%s, ignored"), arg);
2146
          return 0;
2147
        }
2148
      break;
2149
    case OPTION_DISP_SIZE:
2150
      {
2151
        int size = atoi(arg);
2152
        switch (size)
2153
          {
2154
          case 1: case 2: case 4:
2155
            default_disp_size = size;
2156
            break;
2157
          default:
2158
            as_warn (_("invalid default displacement size \"%s\". Defaulting to %d."),
2159
                     arg, default_disp_size);
2160
          }
2161
        break;
2162
      }
2163
 
2164
    default:
2165
      return 0;
2166
    }
2167
 
2168
  return 1;
2169
}
2170
 
2171
void
2172
md_show_usage (FILE *stream)
2173
{
2174
  fprintf (stream, _("\
2175
NS32K options:\n\
2176
-m32032 | -m32532       select variant of NS32K architecture\n\
2177
--disp-size-default=<1|2|4>\n"));
2178
}
2179
 
2180
/* This is TC_CONS_FIX_NEW, called by emit_expr in read.c.  */
2181
 
2182
void
2183
cons_fix_new_ns32k (fragS *frag,        /* Which frag? */
2184
                    int where,          /* Where in that frag? */
2185
                    int size,           /* 1, 2  or 4 usually.  */
2186
                    expressionS *exp)   /* Expression.  */
2187
{
2188
  fix_new_ns32k_exp (frag, where, size, exp,
2189
                     0, 2, 0, 0, 0, 0);
2190
}
2191
 
2192
/* We have no need to default values of symbols.  */
2193
 
2194
symbolS *
2195
md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
2196
{
2197
  return 0;
2198
}
2199
 
2200
/* Round up a section size to the appropriate boundary.  */
2201
 
2202
valueT
2203
md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size)
2204
{
2205
  return size;                  /* Byte alignment is fine.  */
2206
}
2207
 
2208
/* Exactly what point is a PC-relative offset relative TO?  On the
2209
   ns32k, they're relative to the start of the instruction.  */
2210
 
2211
long
2212
md_pcrel_from (fixS *fixP)
2213
{
2214
  long res;
2215
 
2216
  res = fixP->fx_where + fixP->fx_frag->fr_address;
2217
#ifdef SEQUENT_COMPATABILITY
2218
  if (frag_bsr (fixP->fx_frag))
2219
    res += 0x12                 /* FOO Kludge alert!  */
2220
#endif
2221
      return res;
2222
}
2223
 
2224
arelent *
2225
tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
2226
{
2227
  arelent *rel;
2228
  bfd_reloc_code_real_type code;
2229
 
2230
  code = reloc (fixp->fx_size, fixp->fx_pcrel, fix_im_disp (fixp));
2231
 
2232
  rel = xmalloc (sizeof (arelent));
2233
  rel->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
2234
  *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
2235
  rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
2236
  if (fixp->fx_pcrel)
2237
    rel->addend = fixp->fx_addnumber;
2238
  else
2239
    rel->addend = 0;
2240
 
2241
  rel->howto = bfd_reloc_type_lookup (stdoutput, code);
2242
  if (!rel->howto)
2243
    {
2244
      const char *name;
2245
 
2246
      name = S_GET_NAME (fixp->fx_addsy);
2247
      if (name == NULL)
2248
        name = _("<unknown>");
2249
      as_fatal (_("Cannot find relocation type for symbol %s, code %d"),
2250
                name, (int) code);
2251
    }
2252
 
2253
  return rel;
2254
}

powered by: WebSVN 2.1.0

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