OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.20.1/] [gas/] [config/] [tc-tic30.c] - Blame information for rev 294

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

Line No. Rev Author Line
1 205 julius
/* tc-c30.c -- Assembly code for the Texas Instruments TMS320C30
2
   Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2009
3
   Free Software Foundation, Inc.
4
   Contributed by Steven Haworth (steve@pm.cse.rmit.edu.au)
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
/* Texas Instruments TMS320C30 machine specific gas.
24
   Written by Steven Haworth (steve@pm.cse.rmit.edu.au).
25
   Bugs & suggestions are completely welcome.  This is free software.
26
   Please help us make it better.  */
27
 
28
#include "as.h"
29
#include "safe-ctype.h"
30
#include "opcode/tic30.h"
31
 
32
/* Put here all non-digit non-letter characters that may occur in an
33
   operand.  */
34
static char operand_special_chars[] = "%$-+(,)*._~/<>&^!:[@]";
35
static char *ordinal_names[] =
36
{
37
  "first", "second", "third", "fourth", "fifth"
38
};
39
 
40
const char comment_chars[]        = ";";
41
const char line_comment_chars[]   = "*";
42
const char line_separator_chars[] = "";
43
 
44
const char *md_shortopts = "";
45
struct option md_longopts[] =
46
{
47
  {NULL, no_argument, NULL, 0}
48
};
49
 
50
size_t md_longopts_size = sizeof (md_longopts);
51
 
52
/* Chars that mean this number is a floating point constant.
53
   As in 0f12.456
54
   or    0d1.2345e12.  */
55
const char FLT_CHARS[] = "fFdDxX";
56
 
57
/* Chars that can be used to separate mant from exp in floating point
58
   nums.  */
59
const char EXP_CHARS[] = "eE";
60
 
61
/* Tables for lexical analysis.  */
62
static char opcode_chars[256];
63
static char register_chars[256];
64
static char operand_chars[256];
65
static char space_chars[256];
66
static char identifier_chars[256];
67
static char digit_chars[256];
68
 
69
/* Lexical macros.  */
70
#define is_opcode_char(x)     (opcode_chars     [(unsigned char) x])
71
#define is_operand_char(x)    (operand_chars    [(unsigned char) x])
72
#define is_register_char(x)   (register_chars   [(unsigned char) x])
73
#define is_space_char(x)      (space_chars      [(unsigned char) x])
74
#define is_identifier_char(x) (identifier_chars [(unsigned char) x])
75
#define is_digit_char(x)      (digit_chars      [(unsigned char) x])
76
 
77
const pseudo_typeS md_pseudo_table[] =
78
{
79
  {0, 0, 0}
80
};
81
 
82
static int ATTRIBUTE_PRINTF_1
83
debug (const char *string, ...)
84
{
85
  if (flag_debug)
86
    {
87
      char str[100];
88
 
89
      VA_OPEN (argptr, string);
90
      VA_FIXEDARG (argptr, const char *, string);
91
      vsprintf (str, string, argptr);
92
      VA_CLOSE (argptr);
93
      if (str[0] == '\0')
94
        return (0);
95
      fputs (str, USE_STDOUT ? stdout : stderr);
96
      return strlen (str);
97
    }
98
  else
99
    return 0;
100
}
101
 
102
/* Hash table for opcode lookup.  */
103
static struct hash_control *op_hash;
104
/* Hash table for parallel opcode lookup.  */
105
static struct hash_control *parop_hash;
106
/* Hash table for register lookup.  */
107
static struct hash_control *reg_hash;
108
/* Hash table for indirect addressing lookup.  */
109
static struct hash_control *ind_hash;
110
 
111
void
112
md_begin (void)
113
{
114
  const char *hash_err;
115
 
116
  debug ("In md_begin()\n");
117
  op_hash = hash_new ();
118
 
119
  {
120
    const insn_template *current_optab = tic30_optab;
121
 
122
    for (; current_optab < tic30_optab_end; current_optab++)
123
      {
124
        hash_err = hash_insert (op_hash, current_optab->name,
125
                                (char *) current_optab);
126
        if (hash_err)
127
          as_fatal ("Internal Error: Can't Hash %s: %s",
128
                    current_optab->name, hash_err);
129
      }
130
  }
131
 
132
  parop_hash = hash_new ();
133
 
134
  {
135
    const partemplate *current_parop = tic30_paroptab;
136
 
137
    for (; current_parop < tic30_paroptab_end; current_parop++)
138
      {
139
        hash_err = hash_insert (parop_hash, current_parop->name,
140
                                (char *) current_parop);
141
        if (hash_err)
142
          as_fatal ("Internal Error: Can't Hash %s: %s",
143
                    current_parop->name, hash_err);
144
      }
145
  }
146
 
147
  reg_hash = hash_new ();
148
 
149
  {
150
    const reg *current_reg = tic30_regtab;
151
 
152
    for (; current_reg < tic30_regtab_end; current_reg++)
153
      {
154
        hash_err = hash_insert (reg_hash, current_reg->name,
155
                                (char *) current_reg);
156
        if (hash_err)
157
          as_fatal ("Internal Error: Can't Hash %s: %s",
158
                    current_reg->name, hash_err);
159
      }
160
  }
161
 
162
  ind_hash = hash_new ();
163
 
164
  {
165
    const ind_addr_type *current_ind = tic30_indaddr_tab;
166
 
167
    for (; current_ind < tic30_indaddrtab_end; current_ind++)
168
      {
169
        hash_err = hash_insert (ind_hash, current_ind->syntax,
170
                                (char *) current_ind);
171
        if (hash_err)
172
          as_fatal ("Internal Error: Can't Hash %s: %s",
173
                    current_ind->syntax, hash_err);
174
      }
175
  }
176
 
177
  /* Fill in lexical tables:  opcode_chars, operand_chars, space_chars.  */
178
  {
179
    int c;
180
    char *p;
181
 
182
    for (c = 0; c < 256; c++)
183
      {
184
        if (ISLOWER (c) || ISDIGIT (c))
185
          {
186
            opcode_chars[c] = c;
187
            register_chars[c] = c;
188
          }
189
        else if (ISUPPER (c))
190
          {
191
            opcode_chars[c] = TOLOWER (c);
192
            register_chars[c] = opcode_chars[c];
193
          }
194
        else if (c == ')' || c == '(')
195
          register_chars[c] = c;
196
 
197
        if (ISUPPER (c) || ISLOWER (c) || ISDIGIT (c))
198
          operand_chars[c] = c;
199
 
200
        if (ISDIGIT (c) || c == '-')
201
          digit_chars[c] = c;
202
 
203
        if (ISALPHA (c) || c == '_' || c == '.' || ISDIGIT (c))
204
          identifier_chars[c] = c;
205
 
206
        if (c == ' ' || c == '\t')
207
          space_chars[c] = c;
208
 
209
        if (c == '_')
210
          opcode_chars[c] = c;
211
      }
212
    for (p = operand_special_chars; *p != '\0'; p++)
213
      operand_chars[(unsigned char) *p] = *p;
214
  }
215
}
216
 
217
/* Address Mode OR values.  */
218
#define AM_Register  0x00000000
219
#define AM_Direct    0x00200000
220
#define AM_Indirect  0x00400000
221
#define AM_Immediate 0x00600000
222
#define AM_NotReq    0xFFFFFFFF
223
 
224
/* PC Relative OR values.  */
225
#define PC_Register 0x00000000
226
#define PC_Relative 0x02000000
227
 
228
typedef struct
229
{
230
  unsigned op_type;
231
  struct
232
  {
233
    int resolved;
234
    unsigned address;
235
    char *label;
236
    expressionS direct_expr;
237
  } direct;
238
  struct
239
  {
240
    unsigned mod;
241
    int ARnum;
242
    unsigned char disp;
243
  } indirect;
244
  struct
245
  {
246
    unsigned opcode;
247
  } reg;
248
  struct
249
  {
250
    int resolved;
251
    int decimal_found;
252
    float f_number;
253
    int s_number;
254
    unsigned int u_number;
255
    char *label;
256
    expressionS imm_expr;
257
  } immediate;
258
} operand;
259
 
260
insn_template *opcode;
261
 
262
struct tic30_insn
263
{
264
  insn_template *tm;            /* Template of current instruction.  */
265
  unsigned opcode;              /* Final opcode.  */
266
  unsigned int operands;        /* Number of given operands.  */
267
  /* Type of operand given in instruction.  */
268
  operand *operand_type[MAX_OPERANDS];
269
  unsigned addressing_mode;     /* Final addressing mode of instruction.  */
270
};
271
 
272
struct tic30_insn insn;
273
static int found_parallel_insn;
274
 
275
static char output_invalid_buf[sizeof (unsigned char) * 2 + 6];
276
 
277
static char *
278
output_invalid (char c)
279
{
280
  if (ISPRINT (c))
281
    snprintf (output_invalid_buf, sizeof (output_invalid_buf),
282
              "'%c'", c);
283
  else
284
    snprintf (output_invalid_buf, sizeof (output_invalid_buf),
285
              "(0x%x)", (unsigned char) c);
286
  return output_invalid_buf;
287
}
288
 
289
/* next_line points to the next line after the current instruction
290
   (current_line).  Search for the parallel bars, and if found, merge two
291
   lines into internal syntax for a parallel instruction:
292
     q_[INSN1]_[INSN2] [OPERANDS1] | [OPERANDS2]
293
   By this stage, all comments are scrubbed, and only the bare lines are
294
   given.  */
295
 
296
#define NONE           0
297
#define START_OPCODE   1
298
#define END_OPCODE     2
299
#define START_OPERANDS 3
300
#define END_OPERANDS   4
301
 
302
static char *
303
tic30_find_parallel_insn (char *current_line, char *next_line)
304
{
305
  int found_parallel = 0;
306
  char first_opcode[256];
307
  char second_opcode[256];
308
  char first_operands[256];
309
  char second_operands[256];
310
  char *parallel_insn;
311
 
312
  debug ("In tic30_find_parallel_insn()\n");
313
  while (!is_end_of_line[(unsigned char) *next_line])
314
    {
315
      if (*next_line == PARALLEL_SEPARATOR
316
          && *(next_line + 1) == PARALLEL_SEPARATOR)
317
        {
318
          found_parallel = 1;
319
          next_line++;
320
          break;
321
        }
322
      next_line++;
323
    }
324
  if (!found_parallel)
325
    return NULL;
326
  debug ("Found a parallel instruction\n");
327
 
328
  {
329
    int i;
330
    char *opcode, *operands, *line;
331
 
332
    for (i = 0; i < 2; i++)
333
      {
334
        if (i == 0)
335
          {
336
            opcode = &first_opcode[0];
337
            operands = &first_operands[0];
338
            line = current_line;
339
          }
340
        else
341
          {
342
            opcode = &second_opcode[0];
343
            operands = &second_operands[0];
344
            line = next_line;
345
          }
346
 
347
        {
348
          int search_status = NONE;
349
          int char_ptr = 0;
350
          char c;
351
 
352
          while (!is_end_of_line[(unsigned char) (c = *line)])
353
            {
354
              if (is_opcode_char (c) && search_status == NONE)
355
                {
356
                  opcode[char_ptr++] = TOLOWER (c);
357
                  search_status = START_OPCODE;
358
                }
359
              else if (is_opcode_char (c) && search_status == START_OPCODE)
360
                opcode[char_ptr++] = TOLOWER (c);
361
              else if (!is_opcode_char (c) && search_status == START_OPCODE)
362
                {
363
                  opcode[char_ptr] = '\0';
364
                  char_ptr = 0;
365
                  search_status = END_OPCODE;
366
                }
367
              else if (is_operand_char (c) && search_status == START_OPERANDS)
368
                operands[char_ptr++] = c;
369
 
370
              if (is_operand_char (c) && search_status == END_OPCODE)
371
                {
372
                  operands[char_ptr++] = c;
373
                  search_status = START_OPERANDS;
374
                }
375
 
376
              line++;
377
            }
378
          if (search_status != START_OPERANDS)
379
            return NULL;
380
          operands[char_ptr] = '\0';
381
        }
382
      }
383
  }
384
  parallel_insn = malloc (strlen (first_opcode) + strlen (first_operands)
385
                          + strlen (second_opcode) + strlen (second_operands) + 8);
386
  sprintf (parallel_insn, "q_%s_%s %s | %s",
387
           first_opcode, second_opcode,
388
           first_operands, second_operands);
389
  debug ("parallel insn = %s\n", parallel_insn);
390
  return parallel_insn;
391
}
392
 
393
#undef NONE
394
#undef START_OPCODE
395
#undef END_OPCODE
396
#undef START_OPERANDS
397
#undef END_OPERANDS
398
 
399
static operand *
400
tic30_operand (char *token)
401
{
402
  unsigned int count;
403
  char ind_buffer[strlen (token)];
404
  operand *current_op;
405
 
406
  debug ("In tic30_operand with %s\n", token);
407
  current_op = malloc (sizeof (* current_op));
408
  memset (current_op, '\0', sizeof (operand));
409
 
410
  if (*token == DIRECT_REFERENCE)
411
    {
412
      char *token_posn = token + 1;
413
      int direct_label = 0;
414
 
415
      debug ("Found direct reference\n");
416
      while (*token_posn)
417
        {
418
          if (!is_digit_char (*token_posn))
419
            direct_label = 1;
420
          token_posn++;
421
        }
422
 
423
      if (direct_label)
424
        {
425
          char *save_input_line_pointer;
426
          segT retval;
427
 
428
          debug ("Direct reference is a label\n");
429
          current_op->direct.label = token + 1;
430
          save_input_line_pointer = input_line_pointer;
431
          input_line_pointer = token + 1;
432
          debug ("Current input_line_pointer: %s\n", input_line_pointer);
433
          retval = expression (&current_op->direct.direct_expr);
434
 
435
          debug ("Expression type: %d\n",
436
                 current_op->direct.direct_expr.X_op);
437
          debug ("Expression addnum: %ld\n",
438
                 (long) current_op->direct.direct_expr.X_add_number);
439
          debug ("Segment: %p\n", retval);
440
 
441
          input_line_pointer = save_input_line_pointer;
442
 
443
          if (current_op->direct.direct_expr.X_op == O_constant)
444
            {
445
              current_op->direct.address =
446
                current_op->direct.direct_expr.X_add_number;
447
              current_op->direct.resolved = 1;
448
            }
449
        }
450
      else
451
        {
452
          debug ("Direct reference is a number\n");
453
          current_op->direct.address = atoi (token + 1);
454
          current_op->direct.resolved = 1;
455
        }
456
      current_op->op_type = Direct;
457
    }
458
  else if (*token == INDIRECT_REFERENCE)
459
    {
460
      /* Indirect reference operand.  */
461
      int found_ar = 0;
462
      int found_disp = 0;
463
      int ar_number = -1;
464
      int disp_number = 0;
465
      int buffer_posn = 1;
466
      ind_addr_type *ind_addr_op;
467
 
468
      debug ("Found indirect reference\n");
469
      ind_buffer[0] = *token;
470
 
471
      for (count = 1; count < strlen (token); count++)
472
        {
473
          /* Strip operand.  */
474
          ind_buffer[buffer_posn] = TOLOWER (*(token + count));
475
 
476
          if ((*(token + count - 1) == 'a' || *(token + count - 1) == 'A')
477
              && (*(token + count) == 'r' || *(token + count) == 'R'))
478
            {
479
              /* AR reference is found, so get its number and remove
480
                 it from the buffer so it can pass through hash_find().  */
481
              if (found_ar)
482
                {
483
                  as_bad (_("More than one AR register found in indirect reference"));
484
                  return NULL;
485
                }
486
              if (*(token + count + 1) < '0' || *(token + count + 1) > '7')
487
                {
488
                  as_bad (_("Illegal AR register in indirect reference"));
489
                  return NULL;
490
                }
491
              ar_number = *(token + count + 1) - '0';
492
              found_ar = 1;
493
              count++;
494
            }
495
 
496
          if (*(token + count) == '(')
497
            {
498
              /* Parenthesis found, so check if a displacement value is
499
                 inside.  If so, get the value and remove it from the
500
                 buffer.  */
501
              if (is_digit_char (*(token + count + 1)))
502
                {
503
                  char disp[10];
504
                  int disp_posn = 0;
505
 
506
                  if (found_disp)
507
                    {
508
                      as_bad (_("More than one displacement found in indirect reference"));
509
                      return NULL;
510
                    }
511
                  count++;
512
                  while (*(token + count) != ')')
513
                    {
514
                      if (!is_digit_char (*(token + count)))
515
                        {
516
                          as_bad (_("Invalid displacement in indirect reference"));
517
                          return NULL;
518
                        }
519
                      disp[disp_posn++] = *(token + (count++));
520
                    }
521
                  disp[disp_posn] = '\0';
522
                  disp_number = atoi (disp);
523
                  count--;
524
                  found_disp = 1;
525
                }
526
            }
527
          buffer_posn++;
528
        }
529
 
530
      ind_buffer[buffer_posn] = '\0';
531
      if (!found_ar)
532
        {
533
          as_bad (_("AR register not found in indirect reference"));
534
          return NULL;
535
        }
536
 
537
      ind_addr_op = (ind_addr_type *) hash_find (ind_hash, ind_buffer);
538
      if (ind_addr_op)
539
        {
540
          debug ("Found indirect reference: %s\n", ind_addr_op->syntax);
541
          if (ind_addr_op->displacement == IMPLIED_DISP)
542
            {
543
              found_disp = 1;
544
              disp_number = 1;
545
            }
546
          else if ((ind_addr_op->displacement == DISP_REQUIRED) && !found_disp)
547
            {
548
              /* Maybe an implied displacement of 1 again.  */
549
              as_bad (_("required displacement wasn't given in indirect reference"));
550
              return 0;
551
            }
552
        }
553
      else
554
        {
555
          as_bad (_("illegal indirect reference"));
556
          return NULL;
557
        }
558
 
559
      if (found_disp && (disp_number < 0 || disp_number > 255))
560
        {
561
          as_bad (_("displacement must be an unsigned 8-bit number"));
562
          return NULL;
563
        }
564
 
565
      current_op->indirect.mod = ind_addr_op->modfield;
566
      current_op->indirect.disp = disp_number;
567
      current_op->indirect.ARnum = ar_number;
568
      current_op->op_type = Indirect;
569
    }
570
  else
571
    {
572
      reg *regop = (reg *) hash_find (reg_hash, token);
573
 
574
      if (regop)
575
        {
576
          debug ("Found register operand: %s\n", regop->name);
577
          if (regop->regtype == REG_ARn)
578
            current_op->op_type = ARn;
579
          else if (regop->regtype == REG_Rn)
580
            current_op->op_type = Rn;
581
          else if (regop->regtype == REG_DP)
582
            current_op->op_type = DPReg;
583
          else
584
            current_op->op_type = OtherReg;
585
          current_op->reg.opcode = regop->opcode;
586
        }
587
      else
588
        {
589
          if (!is_digit_char (*token)
590
              || *(token + 1) == 'x'
591
              || strchr (token, 'h'))
592
            {
593
              char *save_input_line_pointer;
594
              segT retval;
595
 
596
              debug ("Probably a label: %s\n", token);
597
              current_op->immediate.label = malloc (strlen (token) + 1);
598
              strcpy (current_op->immediate.label, token);
599
              current_op->immediate.label[strlen (token)] = '\0';
600
              save_input_line_pointer = input_line_pointer;
601
              input_line_pointer = token;
602
 
603
              debug ("Current input_line_pointer: %s\n", input_line_pointer);
604
              retval = expression (&current_op->immediate.imm_expr);
605
              debug ("Expression type: %d\n",
606
                     current_op->immediate.imm_expr.X_op);
607
              debug ("Expression addnum: %ld\n",
608
                     (long) current_op->immediate.imm_expr.X_add_number);
609
              debug ("Segment: %p\n", retval);
610
              input_line_pointer = save_input_line_pointer;
611
 
612
              if (current_op->immediate.imm_expr.X_op == O_constant)
613
                {
614
                  current_op->immediate.s_number
615
                    = current_op->immediate.imm_expr.X_add_number;
616
                  current_op->immediate.u_number
617
                    = (unsigned int) current_op->immediate.imm_expr.X_add_number;
618
                  current_op->immediate.resolved = 1;
619
                }
620
            }
621
          else
622
            {
623
              unsigned count;
624
 
625
              debug ("Found a number or displacement\n");
626
              for (count = 0; count < strlen (token); count++)
627
                if (*(token + count) == '.')
628
                  current_op->immediate.decimal_found = 1;
629
              current_op->immediate.label = malloc (strlen (token) + 1);
630
              strcpy (current_op->immediate.label, token);
631
              current_op->immediate.label[strlen (token)] = '\0';
632
              current_op->immediate.f_number = (float) atof (token);
633
              current_op->immediate.s_number = (int) atoi (token);
634
              current_op->immediate.u_number = (unsigned int) atoi (token);
635
              current_op->immediate.resolved = 1;
636
            }
637
          current_op->op_type = Disp | Abs24 | Imm16 | Imm24;
638
          if (current_op->immediate.u_number <= 31)
639
            current_op->op_type |= IVector;
640
        }
641
    }
642
  return current_op;
643
}
644
 
645
struct tic30_par_insn
646
{
647
  partemplate *tm;              /* Template of current parallel instruction.  */
648
  unsigned operands[2];         /* Number of given operands for each insn.  */
649
  /* Type of operand given in instruction.  */
650
  operand *operand_type[2][MAX_OPERANDS];
651
  int swap_operands;            /* Whether to swap operands around.  */
652
  unsigned p_field;             /* Value of p field in multiply add/sub instructions.  */
653
  unsigned opcode;              /* Final opcode.  */
654
};
655
 
656
struct tic30_par_insn p_insn;
657
 
658
static int
659
tic30_parallel_insn (char *token)
660
{
661
  static partemplate *p_opcode;
662
  char *current_posn = token;
663
  char *token_start;
664
  char save_char;
665
 
666
  debug ("In tic30_parallel_insn with %s\n", token);
667
  memset (&p_insn, '\0', sizeof (p_insn));
668
 
669
  while (is_opcode_char (*current_posn))
670
    current_posn++;
671
  {
672
    /* Find instruction.  */
673
    save_char = *current_posn;
674
    *current_posn = '\0';
675
    p_opcode = (partemplate *) hash_find (parop_hash, token);
676
    if (p_opcode)
677
      {
678
        debug ("Found instruction %s\n", p_opcode->name);
679
        p_insn.tm = p_opcode;
680
      }
681
    else
682
      {
683
        char first_opcode[6] = {0};
684
        char second_opcode[6] = {0};
685
        unsigned int i;
686
        int current_opcode = -1;
687
        int char_ptr = 0;
688
 
689
        for (i = 0; i < strlen (token); i++)
690
          {
691
            char ch = *(token + i);
692
 
693
            if (ch == '_' && current_opcode == -1)
694
              {
695
                current_opcode = 0;
696
                continue;
697
              }
698
 
699
            if (ch == '_' && current_opcode == 0)
700
              {
701
                current_opcode = 1;
702
                char_ptr = 0;
703
                continue;
704
              }
705
 
706
            switch (current_opcode)
707
              {
708
              case 0:
709
                first_opcode[char_ptr++] = ch;
710
                break;
711
              case 1:
712
                second_opcode[char_ptr++] = ch;
713
                break;
714
              }
715
          }
716
 
717
        debug ("first_opcode = %s\n", first_opcode);
718
        debug ("second_opcode = %s\n", second_opcode);
719
        sprintf (token, "q_%s_%s", second_opcode, first_opcode);
720
        p_opcode = (partemplate *) hash_find (parop_hash, token);
721
 
722
        if (p_opcode)
723
          {
724
            debug ("Found instruction %s\n", p_opcode->name);
725
            p_insn.tm = p_opcode;
726
            p_insn.swap_operands = 1;
727
          }
728
        else
729
          return 0;
730
      }
731
    *current_posn = save_char;
732
  }
733
 
734
  {
735
    /* Find operands.  */
736
    int paren_not_balanced;
737
    int expecting_operand = 0;
738
    int found_separator = 0;
739
 
740
    do
741
      {
742
        /* Skip optional white space before operand.  */
743
        while (!is_operand_char (*current_posn)
744
               && *current_posn != END_OF_INSN)
745
          {
746
            if (!is_space_char (*current_posn)
747
                && *current_posn != PARALLEL_SEPARATOR)
748
              {
749
                as_bad (_("Invalid character %s before %s operand"),
750
                        output_invalid (*current_posn),
751
                        ordinal_names[insn.operands]);
752
                return 1;
753
              }
754
            if (*current_posn == PARALLEL_SEPARATOR)
755
              found_separator = 1;
756
            current_posn++;
757
          }
758
 
759
        token_start = current_posn;
760
        paren_not_balanced = 0;
761
 
762
        while (paren_not_balanced || *current_posn != ',')
763
          {
764
            if (*current_posn == END_OF_INSN)
765
              {
766
                if (paren_not_balanced)
767
                  {
768
                    as_bad (_("Unbalanced parenthesis in %s operand."),
769
                            ordinal_names[insn.operands]);
770
                    return 1;
771
                  }
772
                else
773
                  break;
774
              }
775
            else if (*current_posn == PARALLEL_SEPARATOR)
776
              {
777
                while (is_space_char (*(current_posn - 1)))
778
                  current_posn--;
779
                break;
780
              }
781
            else if (!is_operand_char (*current_posn)
782
                     && !is_space_char (*current_posn))
783
              {
784
                as_bad (_("Invalid character %s in %s operand"),
785
                        output_invalid (*current_posn),
786
                        ordinal_names[insn.operands]);
787
                return 1;
788
              }
789
 
790
            if (*current_posn == '(')
791
              ++paren_not_balanced;
792
            if (*current_posn == ')')
793
              --paren_not_balanced;
794
            current_posn++;
795
          }
796
 
797
        if (current_posn != token_start)
798
          {
799
            /* Yes, we've read in another operand.  */
800
            p_insn.operands[found_separator]++;
801
            if (p_insn.operands[found_separator] > MAX_OPERANDS)
802
              {
803
                as_bad (_("Spurious operands; (%d operands/instruction max)"),
804
                        MAX_OPERANDS);
805
                return 1;
806
              }
807
 
808
            /* Now parse operand adding info to 'insn' as we go along.  */
809
            save_char = *current_posn;
810
            *current_posn = '\0';
811
            p_insn.operand_type[found_separator][p_insn.operands[found_separator] - 1] =
812
              tic30_operand (token_start);
813
            *current_posn = save_char;
814
            if (!p_insn.operand_type[found_separator][p_insn.operands[found_separator] - 1])
815
              return 1;
816
          }
817
        else
818
          {
819
            if (expecting_operand)
820
              {
821
                as_bad (_("Expecting operand after ','; got nothing"));
822
                return 1;
823
              }
824
            if (*current_posn == ',')
825
              {
826
                as_bad (_("Expecting operand before ','; got nothing"));
827
                return 1;
828
              }
829
          }
830
 
831
        /* Now *current_posn must be either ',' or END_OF_INSN.  */
832
        if (*current_posn == ',')
833
          {
834
            if (*++current_posn == END_OF_INSN)
835
              {
836
                /* Just skip it, if it's \n complain.  */
837
                as_bad (_("Expecting operand after ','; got nothing"));
838
                return 1;
839
              }
840
            expecting_operand = 1;
841
          }
842
      }
843
    while (*current_posn != END_OF_INSN);
844
  }
845
 
846
  if (p_insn.swap_operands)
847
    {
848
      int temp_num, i;
849
      operand *temp_op;
850
 
851
      temp_num = p_insn.operands[0];
852
      p_insn.operands[0] = p_insn.operands[1];
853
      p_insn.operands[1] = temp_num;
854
      for (i = 0; i < MAX_OPERANDS; i++)
855
        {
856
          temp_op = p_insn.operand_type[0][i];
857
          p_insn.operand_type[0][i] = p_insn.operand_type[1][i];
858
          p_insn.operand_type[1][i] = temp_op;
859
        }
860
    }
861
 
862
  if (p_insn.operands[0] != p_insn.tm->operands_1)
863
    {
864
      as_bad (_("incorrect number of operands given in the first instruction"));
865
      return 1;
866
    }
867
 
868
  if (p_insn.operands[1] != p_insn.tm->operands_2)
869
    {
870
      as_bad (_("incorrect number of operands given in the second instruction"));
871
      return 1;
872
    }
873
 
874
  debug ("Number of operands in first insn: %d\n", p_insn.operands[0]);
875
  debug ("Number of operands in second insn: %d\n", p_insn.operands[1]);
876
 
877
  {
878
    /* Now check if operands are correct.  */
879
    int count;
880
    int num_rn = 0;
881
    int num_ind = 0;
882
 
883
    for (count = 0; count < 2; count++)
884
      {
885
        unsigned int i;
886
        for (i = 0; i < p_insn.operands[count]; i++)
887
          {
888
            if ((p_insn.operand_type[count][i]->op_type &
889
                 p_insn.tm->operand_types[count][i]) == 0)
890
              {
891
                as_bad (_("%s instruction, operand %d doesn't match"),
892
                        ordinal_names[count], i + 1);
893
                return 1;
894
              }
895
 
896
            /* Get number of R register and indirect reference contained
897
               within the first two operands of each instruction.  This is
898
               required for the multiply parallel instructions which require
899
               two R registers and two indirect references, but not in any
900
               particular place.  */
901
            if ((p_insn.operand_type[count][i]->op_type & Rn) && i < 2)
902
              num_rn++;
903
            else if ((p_insn.operand_type[count][i]->op_type & Indirect)
904
                     && i < 2)
905
              num_ind++;
906
          }
907
      }
908
 
909
    if ((p_insn.tm->operand_types[0][0] & (Indirect | Rn))
910
        == (Indirect | Rn))
911
      {
912
        /* Check for the multiply instructions.  */
913
        if (num_rn != 2)
914
          {
915
            as_bad (_("incorrect format for multiply parallel instruction"));
916
            return 1;
917
          }
918
 
919
        if (num_ind != 2)
920
          {
921
            /* Shouldn't get here.  */
922
            as_bad (_("incorrect format for multiply parallel instruction"));
923
            return 1;
924
          }
925
 
926
        if ((p_insn.operand_type[0][2]->reg.opcode != 0x00)
927
            && (p_insn.operand_type[0][2]->reg.opcode != 0x01))
928
          {
929
            as_bad (_("destination for multiply can only be R0 or R1"));
930
            return 1;
931
          }
932
 
933
        if ((p_insn.operand_type[1][2]->reg.opcode != 0x02)
934
            && (p_insn.operand_type[1][2]->reg.opcode != 0x03))
935
          {
936
            as_bad (_("destination for add/subtract can only be R2 or R3"));
937
            return 1;
938
          }
939
 
940
        /* Now determine the P field for the instruction.  */
941
        if (p_insn.operand_type[0][0]->op_type & Indirect)
942
          {
943
            if (p_insn.operand_type[0][1]->op_type & Indirect)
944
              p_insn.p_field = 0x00000000;      /* Ind * Ind, Rn  +/- Rn.  */
945
            else if (p_insn.operand_type[1][0]->op_type & Indirect)
946
              p_insn.p_field = 0x01000000;      /* Ind * Rn,  Ind +/- Rn.  */
947
            else
948
              p_insn.p_field = 0x03000000;      /* Ind * Rn,  Rn  +/- Ind.  */
949
          }
950
        else
951
          {
952
            if (p_insn.operand_type[0][1]->op_type & Rn)
953
              p_insn.p_field = 0x02000000;      /* Rn  * Rn,  Ind +/- Ind.  */
954
            else if (p_insn.operand_type[1][0]->op_type & Indirect)
955
              {
956
                operand *temp;
957
                p_insn.p_field = 0x01000000;    /* Rn  * Ind, Ind +/- Rn.  */
958
                /* Need to swap the two multiply operands around so that
959
                   everything is in its place for the opcode makeup.
960
                   ie so Ind * Rn, Ind +/- Rn.  */
961
                temp = p_insn.operand_type[0][0];
962
                p_insn.operand_type[0][0] = p_insn.operand_type[0][1];
963
                p_insn.operand_type[0][1] = temp;
964
              }
965
            else
966
              {
967
                operand *temp;
968
                p_insn.p_field = 0x03000000;    /* Rn  * Ind, Rn  +/- Ind.  */
969
                temp = p_insn.operand_type[0][0];
970
                p_insn.operand_type[0][0] = p_insn.operand_type[0][1];
971
                p_insn.operand_type[0][1] = temp;
972
              }
973
          }
974
      }
975
  }
976
 
977
  debug ("P field: %08X\n", p_insn.p_field);
978
 
979
  /* Finalise opcode.  This is easier for parallel instructions as they have
980
     to be fully resolved, there are no memory addresses allowed, except
981
     through indirect addressing, so there are no labels to resolve.  */
982
  p_insn.opcode = p_insn.tm->base_opcode;
983
 
984
  switch (p_insn.tm->oporder)
985
    {
986
    case OO_4op1:
987
      p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
988
      p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
989
      p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
990
      p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
991
      p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
992
      p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 22);
993
      break;
994
 
995
    case OO_4op2:
996
      p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
997
      p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
998
      p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8);
999
      p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11);
1000
      p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 19);
1001
      p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 22);
1002
      if (p_insn.operand_type[1][1]->reg.opcode == p_insn.operand_type[0][1]->reg.opcode)
1003
        as_warn (_("loading the same register in parallel operation"));
1004
      break;
1005
 
1006
    case OO_4op3:
1007
      p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
1008
      p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
1009
      p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
1010
      p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
1011
      p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1012
      p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 22);
1013
      break;
1014
 
1015
    case OO_5op1:
1016
      p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
1017
      p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
1018
      p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
1019
      p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
1020
      p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1021
      p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
1022
      p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22);
1023
      break;
1024
 
1025
    case OO_5op2:
1026
      p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
1027
      p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
1028
      p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
1029
      p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
1030
      p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1031
      p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19);
1032
      p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22);
1033
      break;
1034
 
1035
    case OO_PField:
1036
      p_insn.opcode |= p_insn.p_field;
1037
      if (p_insn.operand_type[0][2]->reg.opcode == 0x01)
1038
        p_insn.opcode |= 0x00800000;
1039
      if (p_insn.operand_type[1][2]->reg.opcode == 0x03)
1040
        p_insn.opcode |= 0x00400000;
1041
 
1042
      switch (p_insn.p_field)
1043
        {
1044
        case 0x00000000:
1045
          p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
1046
          p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
1047
          p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
1048
          p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
1049
          p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16);
1050
          p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 19);
1051
          break;
1052
        case 0x01000000:
1053
          p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum);
1054
          p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 3);
1055
          p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
1056
          p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
1057
          p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16);
1058
          p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
1059
          break;
1060
        case 0x02000000:
1061
          p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum);
1062
          p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3);
1063
          p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8);
1064
          p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11);
1065
          p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 16);
1066
          p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19);
1067
          break;
1068
        case 0x03000000:
1069
          p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum);
1070
          p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3);
1071
          p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
1072
          p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
1073
          p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1074
          p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
1075
          break;
1076
        }
1077
      break;
1078
    }
1079
 
1080
  {
1081
    char *p;
1082
 
1083
    p = frag_more (INSN_SIZE);
1084
    md_number_to_chars (p, (valueT) p_insn.opcode, INSN_SIZE);
1085
  }
1086
 
1087
  {
1088
    unsigned int i, j;
1089
 
1090
    for (i = 0; i < 2; i++)
1091
      for (j = 0; j < p_insn.operands[i]; j++)
1092
        free (p_insn.operand_type[i][j]);
1093
  }
1094
 
1095
  debug ("Final opcode: %08X\n", p_insn.opcode);
1096
  debug ("\n");
1097
 
1098
  return 1;
1099
}
1100
 
1101
/* In order to get gas to ignore any | chars at the start of a line,
1102
   this function returns true if a | is found in a line.  */
1103
 
1104
int
1105
tic30_unrecognized_line (int c)
1106
{
1107
  debug ("In tc_unrecognized_line\n");
1108
  return (c == PARALLEL_SEPARATOR);
1109
}
1110
 
1111
int
1112
md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
1113
                               segT segment ATTRIBUTE_UNUSED)
1114
{
1115
  debug ("In md_estimate_size_before_relax()\n");
1116
  return 0;
1117
}
1118
 
1119
void
1120
md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
1121
                 segT sec ATTRIBUTE_UNUSED,
1122
                 register fragS *fragP ATTRIBUTE_UNUSED)
1123
{
1124
  debug ("In md_convert_frag()\n");
1125
}
1126
 
1127
void
1128
md_apply_fix (fixS *fixP,
1129
               valueT *valP,
1130
               segT seg ATTRIBUTE_UNUSED)
1131
{
1132
  valueT value = *valP;
1133
 
1134
  debug ("In md_apply_fix() with value = %ld\n", (long) value);
1135
  debug ("Values in fixP\n");
1136
  debug ("fx_size = %d\n", fixP->fx_size);
1137
  debug ("fx_pcrel = %d\n", fixP->fx_pcrel);
1138
  debug ("fx_where = %ld\n", fixP->fx_where);
1139
  debug ("fx_offset = %d\n", (int) fixP->fx_offset);
1140
  {
1141
    char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
1142
 
1143
    value /= INSN_SIZE;
1144
    if (fixP->fx_size == 1)
1145
      /* Special fix for LDP instruction.  */
1146
      value = (value & 0x00FF0000) >> 16;
1147
 
1148
    debug ("new value = %ld\n", (long) value);
1149
    md_number_to_chars (buf, value, fixP->fx_size);
1150
  }
1151
 
1152
  if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
1153
    fixP->fx_done = 1;
1154
}
1155
 
1156
int
1157
md_parse_option (int c ATTRIBUTE_UNUSED,
1158
                 char *arg ATTRIBUTE_UNUSED)
1159
{
1160
  debug ("In md_parse_option()\n");
1161
  return 0;
1162
}
1163
 
1164
void
1165
md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
1166
{
1167
  debug ("In md_show_usage()\n");
1168
}
1169
 
1170
symbolS *
1171
md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
1172
{
1173
  debug ("In md_undefined_symbol()\n");
1174
  return (symbolS *) 0;
1175
}
1176
 
1177
valueT
1178
md_section_align (segT segment, valueT size)
1179
{
1180
  debug ("In md_section_align() segment = %p and size = %lu\n",
1181
         segment, (unsigned long) size);
1182
  size = (size + 3) / 4;
1183
  size *= 4;
1184
  debug ("New size value = %lu\n", (unsigned long) size);
1185
  return size;
1186
}
1187
 
1188
long
1189
md_pcrel_from (fixS *fixP)
1190
{
1191
  int offset;
1192
 
1193
  debug ("In md_pcrel_from()\n");
1194
  debug ("fx_where = %ld\n", fixP->fx_where);
1195
  debug ("fx_size = %d\n", fixP->fx_size);
1196
  /* Find the opcode that represents the current instruction in the
1197
     fr_literal storage area, and check bit 21.  Bit 21 contains whether the
1198
     current instruction is a delayed one or not, and then set the offset
1199
     value appropriately.  */
1200
  if (fixP->fx_frag->fr_literal[fixP->fx_where - fixP->fx_size + 1] & 0x20)
1201
    offset = 3;
1202
  else
1203
    offset = 1;
1204
  debug ("offset = %d\n", offset);
1205
  /* PC Relative instructions have a format:
1206
     displacement = Label - (PC + offset)
1207
     This function returns PC + offset where:
1208
     fx_where - fx_size = PC
1209
     INSN_SIZE * offset = offset number of instructions.  */
1210
  return fixP->fx_where - fixP->fx_size + (INSN_SIZE * offset);
1211
}
1212
 
1213
char *
1214
md_atof (int what_statement_type,
1215
         char *literalP,
1216
         int *sizeP)
1217
{
1218
  int prec;
1219
  char *token;
1220
  char keepval;
1221
  unsigned long value;
1222
  float float_value;
1223
 
1224
  debug ("In md_atof()\n");
1225
  debug ("precision = %c\n", what_statement_type);
1226
  debug ("literal = %s\n", literalP);
1227
  debug ("line = ");
1228
  token = input_line_pointer;
1229
  while (!is_end_of_line[(unsigned char) *input_line_pointer]
1230
         && (*input_line_pointer != ','))
1231
    {
1232
      debug ("%c", *input_line_pointer);
1233
      input_line_pointer++;
1234
    }
1235
 
1236
  keepval = *input_line_pointer;
1237
  *input_line_pointer = '\0';
1238
  debug ("\n");
1239
  float_value = (float) atof (token);
1240
  *input_line_pointer = keepval;
1241
  debug ("float_value = %f\n", float_value);
1242
 
1243
  switch (what_statement_type)
1244
    {
1245
    case 'f':
1246
    case 'F':
1247
    case 's':
1248
    case 'S':
1249
      prec = 2;
1250
      break;
1251
 
1252
    case 'd':
1253
    case 'D':
1254
    case 'r':
1255
    case 'R':
1256
      prec = 4;
1257
      break;
1258
 
1259
    default:
1260
      *sizeP = 0;
1261
      return _("Unrecognized or unsupported floating point constant");
1262
    }
1263
 
1264
  if (float_value == 0.0)
1265
    value = (prec == 2) ? 0x00008000L : 0x80000000L;
1266
  else
1267
    {
1268
      unsigned long exp, sign, mant, tmsfloat;
1269
      union
1270
      {
1271
        float f;
1272
        long  l;
1273
      }
1274
      converter;
1275
 
1276
      converter.f = float_value;
1277
      tmsfloat = converter.l;
1278
      sign = tmsfloat & 0x80000000;
1279
      mant = tmsfloat & 0x007FFFFF;
1280
      exp = tmsfloat & 0x7F800000;
1281
      exp <<= 1;
1282
      if (exp == 0xFF000000)
1283
        {
1284
          if (mant == 0)
1285
            value = 0x7F7FFFFF;
1286
          else if (sign == 0)
1287
            value = 0x7F7FFFFF;
1288
          else
1289
            value = 0x7F800000;
1290
        }
1291
      else
1292
        {
1293
          exp -= 0x7F000000;
1294
          if (sign)
1295
            {
1296
              mant = mant & 0x007FFFFF;
1297
              mant = -mant;
1298
              mant = mant & 0x00FFFFFF;
1299
              if (mant == 0)
1300
                {
1301
                  mant |= 0x00800000;
1302
                  exp = (long) exp - 0x01000000;
1303
                }
1304
            }
1305
          tmsfloat = exp | mant;
1306
          value = tmsfloat;
1307
        }
1308
      if (prec == 2)
1309
        {
1310
          long exp, mant;
1311
 
1312
          if (tmsfloat == 0x80000000)
1313
            value = 0x8000;
1314
          else
1315
            {
1316
              value = 0;
1317
              exp = (tmsfloat & 0xFF000000);
1318
              exp >>= 24;
1319
              mant = tmsfloat & 0x007FFFFF;
1320
              if (tmsfloat & 0x00800000)
1321
                {
1322
                  mant |= 0xFF000000;
1323
                  mant += 0x00000800;
1324
                  mant >>= 12;
1325
                  mant |= 0x00000800;
1326
                  mant &= 0x0FFF;
1327
                  if (exp > 7)
1328
                    value = 0x7800;
1329
                }
1330
              else
1331
                {
1332
                  mant |= 0x00800000;
1333
                  mant += 0x00000800;
1334
                  exp += (mant >> 24);
1335
                  mant >>= 12;
1336
                  mant &= 0x07FF;
1337
                  if (exp > 7)
1338
                    value = 0x77FF;
1339
                }
1340
              if (exp < -8)
1341
                value = 0x8000;
1342
              if (value == 0)
1343
                {
1344
                  mant = (exp << 12) | mant;
1345
                  value = mant & 0xFFFF;
1346
                }
1347
            }
1348
        }
1349
    }
1350
  md_number_to_chars (literalP, value, prec);
1351
  *sizeP = prec;
1352
  return NULL;
1353
}
1354
 
1355
void
1356
md_number_to_chars (char *buf, valueT val, int n)
1357
{
1358
  debug ("In md_number_to_chars()\n");
1359
  number_to_chars_bigendian (buf, val, n);
1360
}
1361
 
1362
#define F(SZ,PCREL)             (((SZ) << 1) + (PCREL))
1363
#define MAP(SZ,PCREL,TYPE)      case F(SZ,PCREL): code = (TYPE); break
1364
 
1365
arelent *
1366
tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
1367
{
1368
  arelent *rel;
1369
  bfd_reloc_code_real_type code = 0;
1370
 
1371
  debug ("In tc_gen_reloc()\n");
1372
  debug ("fixP.size = %d\n", fixP->fx_size);
1373
  debug ("fixP.pcrel = %d\n", fixP->fx_pcrel);
1374
  debug ("addsy.name = %s\n", S_GET_NAME (fixP->fx_addsy));
1375
 
1376
  switch (F (fixP->fx_size, fixP->fx_pcrel))
1377
    {
1378
      MAP (1, 0, BFD_RELOC_TIC30_LDP);
1379
      MAP (2, 0, BFD_RELOC_16);
1380
      MAP (3, 0, BFD_RELOC_24);
1381
      MAP (2, 1, BFD_RELOC_16_PCREL);
1382
      MAP (4, 0, BFD_RELOC_32);
1383
    default:
1384
      as_bad (_("Can not do %d byte %srelocation"), fixP->fx_size,
1385
              fixP->fx_pcrel ? _("pc-relative ") : "");
1386
    }
1387
#undef MAP
1388
#undef F
1389
 
1390
  rel = xmalloc (sizeof (* rel));
1391
  gas_assert (rel != 0);
1392
  rel->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
1393
  *rel->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
1394
  rel->address = fixP->fx_frag->fr_address + fixP->fx_where;
1395
  rel->addend = 0;
1396
  rel->howto = bfd_reloc_type_lookup (stdoutput, code);
1397
  if (!rel->howto)
1398
    {
1399
      const char *name;
1400
 
1401
      name = S_GET_NAME (fixP->fx_addsy);
1402
      if (name == NULL)
1403
        name = "<unknown>";
1404
      as_fatal ("Cannot generate relocation type for symbol %s, code %s",
1405
                name, bfd_get_reloc_code_name (code));
1406
    }
1407
  return rel;
1408
}
1409
 
1410
void
1411
md_operand (expressionS *expressionP ATTRIBUTE_UNUSED)
1412
{
1413
  debug ("In md_operand()\n");
1414
}
1415
 
1416
void
1417
md_assemble (char *line)
1418
{
1419
  insn_template *opcode;
1420
  char *current_posn;
1421
  char *token_start;
1422
  char save_char;
1423
  unsigned int count;
1424
 
1425
  debug ("In md_assemble() with argument %s\n", line);
1426
  memset (&insn, '\0', sizeof (insn));
1427
  if (found_parallel_insn)
1428
    {
1429
      debug ("Line is second part of parallel instruction\n\n");
1430
      found_parallel_insn = 0;
1431
      return;
1432
    }
1433
  if ((current_posn =
1434
       tic30_find_parallel_insn (line, input_line_pointer + 1)) == NULL)
1435
    current_posn = line;
1436
  else
1437
    found_parallel_insn = 1;
1438
 
1439
  while (is_space_char (*current_posn))
1440
    current_posn++;
1441
 
1442
  token_start = current_posn;
1443
 
1444
  if (!is_opcode_char (*current_posn))
1445
    {
1446
      as_bad (_("Invalid character %s in opcode"),
1447
              output_invalid (*current_posn));
1448
      return;
1449
    }
1450
  /* Check if instruction is a parallel instruction
1451
     by seeing if the first character is a q.  */
1452
  if (*token_start == 'q')
1453
    {
1454
      if (tic30_parallel_insn (token_start))
1455
        {
1456
          if (found_parallel_insn)
1457
            free (token_start);
1458
          return;
1459
        }
1460
    }
1461
  while (is_opcode_char (*current_posn))
1462
    current_posn++;
1463
  {
1464
    /* Find instruction.  */
1465
    save_char = *current_posn;
1466
    *current_posn = '\0';
1467
    opcode = (insn_template *) hash_find (op_hash, token_start);
1468
    if (opcode)
1469
      {
1470
        debug ("Found instruction %s\n", opcode->name);
1471
        insn.tm = opcode;
1472
      }
1473
    else
1474
      {
1475
        debug ("Didn't find insn\n");
1476
        as_bad (_("Unknown TMS320C30 instruction: %s"), token_start);
1477
        return;
1478
      }
1479
    *current_posn = save_char;
1480
  }
1481
 
1482
  if (*current_posn != END_OF_INSN)
1483
    {
1484
      /* Find operands.  */
1485
      int paren_not_balanced;
1486
      int expecting_operand = 0;
1487
      int this_operand;
1488
      do
1489
        {
1490
          /* Skip optional white space before operand.  */
1491
          while (!is_operand_char (*current_posn)
1492
                 && *current_posn != END_OF_INSN)
1493
            {
1494
              if (!is_space_char (*current_posn))
1495
                {
1496
                  as_bad (_("Invalid character %s before %s operand"),
1497
                          output_invalid (*current_posn),
1498
                          ordinal_names[insn.operands]);
1499
                  return;
1500
                }
1501
              current_posn++;
1502
            }
1503
          token_start = current_posn;
1504
          paren_not_balanced = 0;
1505
          while (paren_not_balanced || *current_posn != ',')
1506
            {
1507
              if (*current_posn == END_OF_INSN)
1508
                {
1509
                  if (paren_not_balanced)
1510
                    {
1511
                      as_bad (_("Unbalanced parenthesis in %s operand."),
1512
                              ordinal_names[insn.operands]);
1513
                      return;
1514
                    }
1515
                  else
1516
                    break;
1517
                }
1518
              else if (!is_operand_char (*current_posn)
1519
                       && !is_space_char (*current_posn))
1520
                {
1521
                  as_bad (_("Invalid character %s in %s operand"),
1522
                          output_invalid (*current_posn),
1523
                          ordinal_names[insn.operands]);
1524
                  return;
1525
                }
1526
              if (*current_posn == '(')
1527
                ++paren_not_balanced;
1528
              if (*current_posn == ')')
1529
                --paren_not_balanced;
1530
              current_posn++;
1531
            }
1532
          if (current_posn != token_start)
1533
            {
1534
              /* Yes, we've read in another operand.  */
1535
              this_operand = insn.operands++;
1536
              if (insn.operands > MAX_OPERANDS)
1537
                {
1538
                  as_bad (_("Spurious operands; (%d operands/instruction max)"),
1539
                          MAX_OPERANDS);
1540
                  return;
1541
                }
1542
 
1543
              /* Now parse operand adding info to 'insn' as we go along.  */
1544
              save_char = *current_posn;
1545
              *current_posn = '\0';
1546
              insn.operand_type[this_operand] = tic30_operand (token_start);
1547
              *current_posn = save_char;
1548
              if (insn.operand_type[this_operand] == NULL)
1549
                return;
1550
            }
1551
          else
1552
            {
1553
              if (expecting_operand)
1554
                {
1555
                  as_bad (_("Expecting operand after ','; got nothing"));
1556
                  return;
1557
                }
1558
              if (*current_posn == ',')
1559
                {
1560
                  as_bad (_("Expecting operand before ','; got nothing"));
1561
                  return;
1562
                }
1563
            }
1564
 
1565
          /* Now *current_posn must be either ',' or END_OF_INSN.  */
1566
          if (*current_posn == ',')
1567
            {
1568
              if (*++current_posn == END_OF_INSN)
1569
                {
1570
                  /* Just skip it, if it's \n complain.  */
1571
                  as_bad (_("Expecting operand after ','; got nothing"));
1572
                  return;
1573
                }
1574
              expecting_operand = 1;
1575
            }
1576
        }
1577
      while (*current_posn != END_OF_INSN);
1578
    }
1579
 
1580
  debug ("Number of operands found: %d\n", insn.operands);
1581
 
1582
  /* Check that number of operands is correct.  */
1583
  if (insn.operands != insn.tm->operands)
1584
    {
1585
      unsigned int i;
1586
      unsigned int numops = insn.tm->operands;
1587
 
1588
      /* If operands are not the same, then see if any of the operands are
1589
         not required.  Then recheck with number of given operands.  If they
1590
         are still not the same, then give an error, otherwise carry on.  */
1591
      for (i = 0; i < insn.tm->operands; i++)
1592
        if (insn.tm->operand_types[i] & NotReq)
1593
          numops--;
1594
      if (insn.operands != numops)
1595
        {
1596
          as_bad (_("Incorrect number of operands given"));
1597
          return;
1598
        }
1599
    }
1600
  insn.addressing_mode = AM_NotReq;
1601
  for (count = 0; count < insn.operands; count++)
1602
    {
1603
      if (insn.operand_type[count]->op_type & insn.tm->operand_types[count])
1604
        {
1605
          debug ("Operand %d matches\n", count + 1);
1606
          /* If instruction has two operands and has an AddressMode
1607
             modifier then set addressing mode type for instruction.  */
1608
          if (insn.tm->opcode_modifier == AddressMode)
1609
            {
1610
              int addr_insn = 0;
1611
              /* Store instruction uses the second
1612
                 operand for the address mode.  */
1613
              if ((insn.tm->operand_types[1] & (Indirect | Direct))
1614
                  == (Indirect | Direct))
1615
                addr_insn = 1;
1616
 
1617
              if (insn.operand_type[addr_insn]->op_type & (AllReg))
1618
                insn.addressing_mode = AM_Register;
1619
              else if (insn.operand_type[addr_insn]->op_type & Direct)
1620
                insn.addressing_mode = AM_Direct;
1621
              else if (insn.operand_type[addr_insn]->op_type & Indirect)
1622
                insn.addressing_mode = AM_Indirect;
1623
              else
1624
                insn.addressing_mode = AM_Immediate;
1625
            }
1626
        }
1627
      else
1628
        {
1629
          as_bad (_("The %s operand doesn't match"), ordinal_names[count]);
1630
          return;
1631
        }
1632
    }
1633
 
1634
  /* Now set the addressing mode for 3 operand instructions.  */
1635
  if ((insn.tm->operand_types[0] & op3T1)
1636
      && (insn.tm->operand_types[1] & op3T2))
1637
    {
1638
      /* Set the addressing mode to the values used for 2 operand
1639
         instructions in the  G addressing field of the opcode.  */
1640
      char *p;
1641
      switch (insn.operand_type[0]->op_type)
1642
        {
1643
        case Rn:
1644
        case ARn:
1645
        case DPReg:
1646
        case OtherReg:
1647
          if (insn.operand_type[1]->op_type & (AllReg))
1648
            insn.addressing_mode = AM_Register;
1649
          else if (insn.operand_type[1]->op_type & Indirect)
1650
            insn.addressing_mode = AM_Direct;
1651
          else
1652
            {
1653
              /* Shouldn't make it to this stage.  */
1654
              as_bad (_("Incompatible first and second operands in instruction"));
1655
              return;
1656
            }
1657
          break;
1658
        case Indirect:
1659
          if (insn.operand_type[1]->op_type & (AllReg))
1660
            insn.addressing_mode = AM_Indirect;
1661
          else if (insn.operand_type[1]->op_type & Indirect)
1662
            insn.addressing_mode = AM_Immediate;
1663
          else
1664
            {
1665
              /* Shouldn't make it to this stage.  */
1666
              as_bad (_("Incompatible first and second operands in instruction"));
1667
              return;
1668
            }
1669
          break;
1670
        }
1671
      /* Now make up the opcode for the 3 operand instructions.  As in
1672
         parallel instructions, there will be no unresolved values, so they
1673
         can be fully formed and added to the frag table.  */
1674
      insn.opcode = insn.tm->base_opcode;
1675
      if (insn.operand_type[0]->op_type & Indirect)
1676
        {
1677
          insn.opcode |= (insn.operand_type[0]->indirect.ARnum);
1678
          insn.opcode |= (insn.operand_type[0]->indirect.mod << 3);
1679
        }
1680
      else
1681
        insn.opcode |= (insn.operand_type[0]->reg.opcode);
1682
 
1683
      if (insn.operand_type[1]->op_type & Indirect)
1684
        {
1685
          insn.opcode |= (insn.operand_type[1]->indirect.ARnum << 8);
1686
          insn.opcode |= (insn.operand_type[1]->indirect.mod << 11);
1687
        }
1688
      else
1689
        insn.opcode |= (insn.operand_type[1]->reg.opcode << 8);
1690
 
1691
      if (insn.operands == 3)
1692
        insn.opcode |= (insn.operand_type[2]->reg.opcode << 16);
1693
 
1694
      insn.opcode |= insn.addressing_mode;
1695
      p = frag_more (INSN_SIZE);
1696
      md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1697
    }
1698
  else
1699
    {
1700
      /* Not a three operand instruction.  */
1701
      char *p;
1702
      int am_insn = -1;
1703
      insn.opcode = insn.tm->base_opcode;
1704
      /* Create frag for instruction - all instructions are 4 bytes long.  */
1705
      p = frag_more (INSN_SIZE);
1706
      if ((insn.operands > 0) && (insn.tm->opcode_modifier == AddressMode))
1707
        {
1708
          insn.opcode |= insn.addressing_mode;
1709
          if (insn.addressing_mode == AM_Indirect)
1710
            {
1711
              /* Determine which operand gives the addressing mode.  */
1712
              if (insn.operand_type[0]->op_type & Indirect)
1713
                am_insn = 0;
1714
              if ((insn.operands > 1)
1715
                  && (insn.operand_type[1]->op_type & Indirect))
1716
                am_insn = 1;
1717
              insn.opcode |= (insn.operand_type[am_insn]->indirect.disp);
1718
              insn.opcode |= (insn.operand_type[am_insn]->indirect.ARnum << 8);
1719
              insn.opcode |= (insn.operand_type[am_insn]->indirect.mod << 11);
1720
              if (insn.operands > 1)
1721
                insn.opcode |= (insn.operand_type[!am_insn]->reg.opcode << 16);
1722
              md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1723
            }
1724
          else if (insn.addressing_mode == AM_Register)
1725
            {
1726
              insn.opcode |= (insn.operand_type[0]->reg.opcode);
1727
              if (insn.operands > 1)
1728
                insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
1729
              md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1730
            }
1731
          else if (insn.addressing_mode == AM_Direct)
1732
            {
1733
              if (insn.operand_type[0]->op_type & Direct)
1734
                am_insn = 0;
1735
              if ((insn.operands > 1)
1736
                  && (insn.operand_type[1]->op_type & Direct))
1737
                am_insn = 1;
1738
              if (insn.operands > 1)
1739
                insn.opcode |=
1740
                  (insn.operand_type[! am_insn]->reg.opcode << 16);
1741
              if (insn.operand_type[am_insn]->direct.resolved == 1)
1742
                {
1743
                  /* Resolved values can be placed straight
1744
                     into instruction word, and output.  */
1745
                  insn.opcode |=
1746
                    (insn.operand_type[am_insn]->direct.address & 0x0000FFFF);
1747
                  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1748
                }
1749
              else
1750
                {
1751
                  /* Unresolved direct addressing mode instruction.  */
1752
                  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1753
                  fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2,
1754
                               & insn.operand_type[am_insn]->direct.direct_expr,
1755
                               0, 0);
1756
                }
1757
            }
1758
          else if (insn.addressing_mode == AM_Immediate)
1759
            {
1760
              if (insn.operand_type[0]->immediate.resolved == 1)
1761
                {
1762
                  char *keeploc;
1763
                  int size;
1764
 
1765
                  if (insn.operands > 1)
1766
                    insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
1767
 
1768
                  switch (insn.tm->imm_arg_type)
1769
                    {
1770
                    case Imm_Float:
1771
                      debug ("Floating point first operand\n");
1772
                      md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1773
 
1774
                      keeploc = input_line_pointer;
1775
                      input_line_pointer =
1776
                        insn.operand_type[0]->immediate.label;
1777
 
1778
                      if (md_atof ('f', p + 2, & size) != 0)
1779
                        {
1780
                          as_bad (_("invalid short form floating point immediate operand"));
1781
                          return;
1782
                        }
1783
 
1784
                      input_line_pointer = keeploc;
1785
                      break;
1786
 
1787
                    case Imm_UInt:
1788
                      debug ("Unsigned int first operand\n");
1789
                      if (insn.operand_type[0]->immediate.decimal_found)
1790
                        as_warn (_("rounding down first operand float to unsigned int"));
1791
                      if (insn.operand_type[0]->immediate.u_number > 0xFFFF)
1792
                        as_warn (_("only lower 16-bits of first operand are used"));
1793
                      insn.opcode |=
1794
                        (insn.operand_type[0]->immediate.u_number & 0x0000FFFFL);
1795
                      md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1796
                      break;
1797
 
1798
                    case Imm_SInt:
1799
                      debug ("Int first operand\n");
1800
 
1801
                      if (insn.operand_type[0]->immediate.decimal_found)
1802
                        as_warn (_("rounding down first operand float to signed int"));
1803
 
1804
                      if (insn.operand_type[0]->immediate.s_number < -32768 ||
1805
                          insn.operand_type[0]->immediate.s_number > 32767)
1806
                        {
1807
                          as_bad (_("first operand is too large for 16-bit signed int"));
1808
                          return;
1809
                        }
1810
                      insn.opcode |=
1811
                        (insn.operand_type[0]->immediate.s_number & 0x0000FFFFL);
1812
                      md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1813
                      break;
1814
                    }
1815
                }
1816
              else
1817
                {
1818
                  /* Unresolved immediate label.  */
1819
                  if (insn.operands > 1)
1820
                    insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
1821
                  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1822
                  fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2,
1823
                               & insn.operand_type[0]->immediate.imm_expr,
1824
                               0, 0);
1825
                }
1826
            }
1827
        }
1828
      else if (insn.tm->opcode_modifier == PCRel)
1829
        {
1830
          /* Conditional Branch and Call instructions.  */
1831
          if ((insn.tm->operand_types[0] & (AllReg | Disp))
1832
              == (AllReg | Disp))
1833
            {
1834
              if (insn.operand_type[0]->op_type & (AllReg))
1835
                {
1836
                  insn.opcode |= (insn.operand_type[0]->reg.opcode);
1837
                  insn.opcode |= PC_Register;
1838
                  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1839
                }
1840
              else
1841
                {
1842
                  insn.opcode |= PC_Relative;
1843
                  if (insn.operand_type[0]->immediate.resolved == 1)
1844
                    {
1845
                      insn.opcode |=
1846
                        (insn.operand_type[0]->immediate.s_number & 0x0000FFFF);
1847
                      md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1848
                    }
1849
                  else
1850
                    {
1851
                      md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1852
                      fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal),
1853
                                   2, & insn.operand_type[0]->immediate.imm_expr,
1854
                                   1, 0);
1855
                    }
1856
                }
1857
            }
1858
          else if ((insn.tm->operand_types[0] & ARn) == ARn)
1859
            {
1860
              /* Decrement and Branch instructions.  */
1861
              insn.opcode |= ((insn.operand_type[0]->reg.opcode - 0x08) << 22);
1862
              if (insn.operand_type[1]->op_type & (AllReg))
1863
                {
1864
                  insn.opcode |= (insn.operand_type[1]->reg.opcode);
1865
                  insn.opcode |= PC_Register;
1866
                  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1867
                }
1868
              else if (insn.operand_type[1]->immediate.resolved == 1)
1869
                {
1870
                  if (insn.operand_type[0]->immediate.decimal_found)
1871
                    {
1872
                      as_bad (_("first operand is floating point"));
1873
                      return;
1874
                    }
1875
                  if (insn.operand_type[0]->immediate.s_number < -32768 ||
1876
                      insn.operand_type[0]->immediate.s_number > 32767)
1877
                    {
1878
                      as_bad (_("first operand is too large for 16-bit signed int"));
1879
                      return;
1880
                    }
1881
                  insn.opcode |= (insn.operand_type[1]->immediate.s_number);
1882
                  insn.opcode |= PC_Relative;
1883
                  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1884
                }
1885
              else
1886
                {
1887
                  insn.opcode |= PC_Relative;
1888
                  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1889
                  fix_new_exp (frag_now, p + 2 - frag_now->fr_literal, 2,
1890
                               & insn.operand_type[1]->immediate.imm_expr,
1891
                               1, 0);
1892
                }
1893
            }
1894
        }
1895
      else if (insn.tm->operand_types[0] == IVector)
1896
        {
1897
          /* Trap instructions.  */
1898
          if (insn.operand_type[0]->op_type & IVector)
1899
            insn.opcode |= (insn.operand_type[0]->immediate.u_number);
1900
          else
1901
            {
1902
              /* Shouldn't get here.  */
1903
              as_bad (_("interrupt vector for trap instruction out of range"));
1904
              return;
1905
            }
1906
          md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1907
        }
1908
      else if (insn.tm->opcode_modifier == StackOp
1909
               || insn.tm->opcode_modifier == Rotate)
1910
        {
1911
          /* Push, Pop and Rotate instructions.  */
1912
          insn.opcode |= (insn.operand_type[0]->reg.opcode << 16);
1913
          md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1914
        }
1915
      else if ((insn.tm->operand_types[0] & (Abs24 | Direct))
1916
               == (Abs24 | Direct))
1917
        {
1918
          /* LDP Instruction needs to be tested
1919
             for before the next section.  */
1920
          if (insn.operand_type[0]->op_type & Direct)
1921
            {
1922
              if (insn.operand_type[0]->direct.resolved == 1)
1923
                {
1924
                  /* Direct addressing uses lower 8 bits of direct address.  */
1925
                  insn.opcode |=
1926
                    (insn.operand_type[0]->direct.address & 0x00FF0000) >> 16;
1927
                  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1928
                }
1929
              else
1930
                {
1931
                  fixS *fix;
1932
 
1933
                  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1934
                  fix = fix_new_exp (frag_now, p + 3 - (frag_now->fr_literal),
1935
                                     1, &insn.operand_type[0]->direct.direct_expr, 0, 0);
1936
                  /* Ensure that the assembler doesn't complain
1937
                     about fitting a 24-bit address into 8 bits.  */
1938
                  fix->fx_no_overflow = 1;
1939
                }
1940
            }
1941
          else
1942
            {
1943
              if (insn.operand_type[0]->immediate.resolved == 1)
1944
                {
1945
                  /* Immediate addressing uses upper 8 bits of address.  */
1946
                  if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF)
1947
                    {
1948
                      as_bad (_("LDP instruction needs a 24-bit operand"));
1949
                      return;
1950
                    }
1951
                  insn.opcode |=
1952
                    ((insn.operand_type[0]->immediate.u_number & 0x00FF0000) >> 16);
1953
                  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1954
                }
1955
              else
1956
                {
1957
                  fixS *fix;
1958
                  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1959
                  fix = fix_new_exp (frag_now, p + 3 - (frag_now->fr_literal),
1960
                                     1, &insn.operand_type[0]->immediate.imm_expr,
1961
                                     0, 0);
1962
                  fix->fx_no_overflow = 1;
1963
                }
1964
            }
1965
        }
1966
      else if (insn.tm->operand_types[0] & (Imm24))
1967
        {
1968
          /* Unconditional Branch and Call instructions.  */
1969
          if (insn.operand_type[0]->immediate.resolved == 1)
1970
            {
1971
              if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF)
1972
                as_warn (_("first operand is too large for a 24-bit displacement"));
1973
              insn.opcode |=
1974
                (insn.operand_type[0]->immediate.u_number & 0x00FFFFFF);
1975
              md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1976
            }
1977
          else
1978
            {
1979
              md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1980
              fix_new_exp (frag_now, p + 1 - (frag_now->fr_literal), 3,
1981
                           & insn.operand_type[0]->immediate.imm_expr, 0, 0);
1982
            }
1983
        }
1984
      else if (insn.tm->operand_types[0] & NotReq)
1985
        /* Check for NOP instruction without arguments.  */
1986
        md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1987
 
1988
      else if (insn.tm->operands == 0)
1989
        /* Check for instructions without operands.  */
1990
        md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1991
    }
1992
  debug ("Addressing mode: %08X\n", insn.addressing_mode);
1993
  {
1994
    unsigned int i;
1995
 
1996
    for (i = 0; i < insn.operands; i++)
1997
      {
1998
        if (insn.operand_type[i]->immediate.label)
1999
          free (insn.operand_type[i]->immediate.label);
2000
        free (insn.operand_type[i]);
2001
      }
2002
  }
2003
  debug ("Final opcode: %08X\n", insn.opcode);
2004
  debug ("\n");
2005
}

powered by: WebSVN 2.1.0

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