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

Subversion Repositories open8_urisc

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

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

Line No. Rev Author Line
1 16 khays
/* 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
  N_("first"), N_("second"), N_("third"), N_("fourth"), N_("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 *op, *operands, *line;
331
 
332
    for (i = 0; i < 2; i++)
333
      {
334
        if (i == 0)
335
          {
336
            op = &first_opcode[0];
337
            operands = &first_operands[0];
338
            line = current_line;
339
          }
340
        else
341
          {
342
            op = &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
                  op[char_ptr++] = TOLOWER (c);
357
                  search_status = START_OPCODE;
358
                }
359
              else if (is_opcode_char (c) && search_status == START_OPCODE)
360
                op[char_ptr++] = TOLOWER (c);
361
              else if (!is_opcode_char (c) && search_status == START_OPCODE)
362
                {
363
                  op[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
              debug ("Found a number or displacement\n");
624
              for (count = 0; count < strlen (token); count++)
625
                if (*(token + count) == '.')
626
                  current_op->immediate.decimal_found = 1;
627
              current_op->immediate.label = malloc (strlen (token) + 1);
628
              strcpy (current_op->immediate.label, token);
629
              current_op->immediate.label[strlen (token)] = '\0';
630
              current_op->immediate.f_number = (float) atof (token);
631
              current_op->immediate.s_number = (int) atoi (token);
632
              current_op->immediate.u_number = (unsigned int) atoi (token);
633
              current_op->immediate.resolved = 1;
634
            }
635
          current_op->op_type = Disp | Abs24 | Imm16 | Imm24;
636
          if (current_op->immediate.u_number <= 31)
637
            current_op->op_type |= IVector;
638
        }
639
    }
640
  return current_op;
641
}
642
 
643
struct tic30_par_insn
644
{
645
  partemplate *tm;              /* Template of current parallel instruction.  */
646
  unsigned operands[2];         /* Number of given operands for each insn.  */
647
  /* Type of operand given in instruction.  */
648
  operand *operand_type[2][MAX_OPERANDS];
649
  int swap_operands;            /* Whether to swap operands around.  */
650
  unsigned p_field;             /* Value of p field in multiply add/sub instructions.  */
651
  unsigned opcode;              /* Final opcode.  */
652
};
653
 
654
struct tic30_par_insn p_insn;
655
 
656
static int
657
tic30_parallel_insn (char *token)
658
{
659
  static partemplate *p_opcode;
660
  char *current_posn = token;
661
  char *token_start;
662
  char save_char;
663
 
664
  debug ("In tic30_parallel_insn with %s\n", token);
665
  memset (&p_insn, '\0', sizeof (p_insn));
666
 
667
  while (is_opcode_char (*current_posn))
668
    current_posn++;
669
  {
670
    /* Find instruction.  */
671
    save_char = *current_posn;
672
    *current_posn = '\0';
673
    p_opcode = (partemplate *) hash_find (parop_hash, token);
674
    if (p_opcode)
675
      {
676
        debug ("Found instruction %s\n", p_opcode->name);
677
        p_insn.tm = p_opcode;
678
      }
679
    else
680
      {
681
        char first_opcode[6] = {0};
682
        char second_opcode[6] = {0};
683
        unsigned int i;
684
        int current_opcode = -1;
685
        int char_ptr = 0;
686
 
687
        for (i = 0; i < strlen (token); i++)
688
          {
689
            char ch = *(token + i);
690
 
691
            if (ch == '_' && current_opcode == -1)
692
              {
693
                current_opcode = 0;
694
                continue;
695
              }
696
 
697
            if (ch == '_' && current_opcode == 0)
698
              {
699
                current_opcode = 1;
700
                char_ptr = 0;
701
                continue;
702
              }
703
 
704
            switch (current_opcode)
705
              {
706
              case 0:
707
                first_opcode[char_ptr++] = ch;
708
                break;
709
              case 1:
710
                second_opcode[char_ptr++] = ch;
711
                break;
712
              }
713
          }
714
 
715
        debug ("first_opcode = %s\n", first_opcode);
716
        debug ("second_opcode = %s\n", second_opcode);
717
        sprintf (token, "q_%s_%s", second_opcode, first_opcode);
718
        p_opcode = (partemplate *) hash_find (parop_hash, token);
719
 
720
        if (p_opcode)
721
          {
722
            debug ("Found instruction %s\n", p_opcode->name);
723
            p_insn.tm = p_opcode;
724
            p_insn.swap_operands = 1;
725
          }
726
        else
727
          return 0;
728
      }
729
    *current_posn = save_char;
730
  }
731
 
732
  {
733
    /* Find operands.  */
734
    int paren_not_balanced;
735
    int expecting_operand = 0;
736
    int found_separator = 0;
737
 
738
    do
739
      {
740
        /* Skip optional white space before operand.  */
741
        while (!is_operand_char (*current_posn)
742
               && *current_posn != END_OF_INSN)
743
          {
744
            if (!is_space_char (*current_posn)
745
                && *current_posn != PARALLEL_SEPARATOR)
746
              {
747
                as_bad (_("Invalid character %s before %s operand"),
748
                        output_invalid (*current_posn),
749
                        ordinal_names[insn.operands]);
750
                return 1;
751
              }
752
            if (*current_posn == PARALLEL_SEPARATOR)
753
              found_separator = 1;
754
            current_posn++;
755
          }
756
 
757
        token_start = current_posn;
758
        paren_not_balanced = 0;
759
 
760
        while (paren_not_balanced || *current_posn != ',')
761
          {
762
            if (*current_posn == END_OF_INSN)
763
              {
764
                if (paren_not_balanced)
765
                  {
766
                    as_bad (_("Unbalanced parenthesis in %s operand."),
767
                            ordinal_names[insn.operands]);
768
                    return 1;
769
                  }
770
                else
771
                  break;
772
              }
773
            else if (*current_posn == PARALLEL_SEPARATOR)
774
              {
775
                while (is_space_char (*(current_posn - 1)))
776
                  current_posn--;
777
                break;
778
              }
779
            else if (!is_operand_char (*current_posn)
780
                     && !is_space_char (*current_posn))
781
              {
782
                as_bad (_("Invalid character %s in %s operand"),
783
                        output_invalid (*current_posn),
784
                        ordinal_names[insn.operands]);
785
                return 1;
786
              }
787
 
788
            if (*current_posn == '(')
789
              ++paren_not_balanced;
790
            if (*current_posn == ')')
791
              --paren_not_balanced;
792
            current_posn++;
793
          }
794
 
795
        if (current_posn != token_start)
796
          {
797
            /* Yes, we've read in another operand.  */
798
            p_insn.operands[found_separator]++;
799
            if (p_insn.operands[found_separator] > MAX_OPERANDS)
800
              {
801
                as_bad (_("Spurious operands; (%d operands/instruction max)"),
802
                        MAX_OPERANDS);
803
                return 1;
804
              }
805
 
806
            /* Now parse operand adding info to 'insn' as we go along.  */
807
            save_char = *current_posn;
808
            *current_posn = '\0';
809
            p_insn.operand_type[found_separator][p_insn.operands[found_separator] - 1] =
810
              tic30_operand (token_start);
811
            *current_posn = save_char;
812
            if (!p_insn.operand_type[found_separator][p_insn.operands[found_separator] - 1])
813
              return 1;
814
          }
815
        else
816
          {
817
            if (expecting_operand)
818
              {
819
                as_bad (_("Expecting operand after ','; got nothing"));
820
                return 1;
821
              }
822
            if (*current_posn == ',')
823
              {
824
                as_bad (_("Expecting operand before ','; got nothing"));
825
                return 1;
826
              }
827
          }
828
 
829
        /* Now *current_posn must be either ',' or END_OF_INSN.  */
830
        if (*current_posn == ',')
831
          {
832
            if (*++current_posn == END_OF_INSN)
833
              {
834
                /* Just skip it, if it's \n complain.  */
835
                as_bad (_("Expecting operand after ','; got nothing"));
836
                return 1;
837
              }
838
            expecting_operand = 1;
839
          }
840
      }
841
    while (*current_posn != END_OF_INSN);
842
  }
843
 
844
  if (p_insn.swap_operands)
845
    {
846
      int temp_num, i;
847
      operand *temp_op;
848
 
849
      temp_num = p_insn.operands[0];
850
      p_insn.operands[0] = p_insn.operands[1];
851
      p_insn.operands[1] = temp_num;
852
      for (i = 0; i < MAX_OPERANDS; i++)
853
        {
854
          temp_op = p_insn.operand_type[0][i];
855
          p_insn.operand_type[0][i] = p_insn.operand_type[1][i];
856
          p_insn.operand_type[1][i] = temp_op;
857
        }
858
    }
859
 
860
  if (p_insn.operands[0] != p_insn.tm->operands_1)
861
    {
862
      as_bad (_("incorrect number of operands given in the first instruction"));
863
      return 1;
864
    }
865
 
866
  if (p_insn.operands[1] != p_insn.tm->operands_2)
867
    {
868
      as_bad (_("incorrect number of operands given in the second instruction"));
869
      return 1;
870
    }
871
 
872
  debug ("Number of operands in first insn: %d\n", p_insn.operands[0]);
873
  debug ("Number of operands in second insn: %d\n", p_insn.operands[1]);
874
 
875
  {
876
    /* Now check if operands are correct.  */
877
    int count;
878
    int num_rn = 0;
879
    int num_ind = 0;
880
 
881
    for (count = 0; count < 2; count++)
882
      {
883
        unsigned int i;
884
        for (i = 0; i < p_insn.operands[count]; i++)
885
          {
886
            if ((p_insn.operand_type[count][i]->op_type &
887
                 p_insn.tm->operand_types[count][i]) == 0)
888
              {
889
                as_bad (_("%s instruction, operand %d doesn't match"),
890
                        ordinal_names[count], i + 1);
891
                return 1;
892
              }
893
 
894
            /* Get number of R register and indirect reference contained
895
               within the first two operands of each instruction.  This is
896
               required for the multiply parallel instructions which require
897
               two R registers and two indirect references, but not in any
898
               particular place.  */
899
            if ((p_insn.operand_type[count][i]->op_type & Rn) && i < 2)
900
              num_rn++;
901
            else if ((p_insn.operand_type[count][i]->op_type & Indirect)
902
                     && i < 2)
903
              num_ind++;
904
          }
905
      }
906
 
907
    if ((p_insn.tm->operand_types[0][0] & (Indirect | Rn))
908
        == (Indirect | Rn))
909
      {
910
        /* Check for the multiply instructions.  */
911
        if (num_rn != 2)
912
          {
913
            as_bad (_("incorrect format for multiply parallel instruction"));
914
            return 1;
915
          }
916
 
917
        if (num_ind != 2)
918
          {
919
            /* Shouldn't get here.  */
920
            as_bad (_("incorrect format for multiply parallel instruction"));
921
            return 1;
922
          }
923
 
924
        if ((p_insn.operand_type[0][2]->reg.opcode != 0x00)
925
            && (p_insn.operand_type[0][2]->reg.opcode != 0x01))
926
          {
927
            as_bad (_("destination for multiply can only be R0 or R1"));
928
            return 1;
929
          }
930
 
931
        if ((p_insn.operand_type[1][2]->reg.opcode != 0x02)
932
            && (p_insn.operand_type[1][2]->reg.opcode != 0x03))
933
          {
934
            as_bad (_("destination for add/subtract can only be R2 or R3"));
935
            return 1;
936
          }
937
 
938
        /* Now determine the P field for the instruction.  */
939
        if (p_insn.operand_type[0][0]->op_type & Indirect)
940
          {
941
            if (p_insn.operand_type[0][1]->op_type & Indirect)
942
              p_insn.p_field = 0x00000000;      /* Ind * Ind, Rn  +/- Rn.  */
943
            else if (p_insn.operand_type[1][0]->op_type & Indirect)
944
              p_insn.p_field = 0x01000000;      /* Ind * Rn,  Ind +/- Rn.  */
945
            else
946
              p_insn.p_field = 0x03000000;      /* Ind * Rn,  Rn  +/- Ind.  */
947
          }
948
        else
949
          {
950
            if (p_insn.operand_type[0][1]->op_type & Rn)
951
              p_insn.p_field = 0x02000000;      /* Rn  * Rn,  Ind +/- Ind.  */
952
            else if (p_insn.operand_type[1][0]->op_type & Indirect)
953
              {
954
                operand *temp;
955
                p_insn.p_field = 0x01000000;    /* Rn  * Ind, Ind +/- Rn.  */
956
                /* Need to swap the two multiply operands around so that
957
                   everything is in its place for the opcode makeup.
958
                   ie so Ind * Rn, Ind +/- Rn.  */
959
                temp = p_insn.operand_type[0][0];
960
                p_insn.operand_type[0][0] = p_insn.operand_type[0][1];
961
                p_insn.operand_type[0][1] = temp;
962
              }
963
            else
964
              {
965
                operand *temp;
966
                p_insn.p_field = 0x03000000;    /* Rn  * Ind, Rn  +/- Ind.  */
967
                temp = p_insn.operand_type[0][0];
968
                p_insn.operand_type[0][0] = p_insn.operand_type[0][1];
969
                p_insn.operand_type[0][1] = temp;
970
              }
971
          }
972
      }
973
  }
974
 
975
  debug ("P field: %08X\n", p_insn.p_field);
976
 
977
  /* Finalise opcode.  This is easier for parallel instructions as they have
978
     to be fully resolved, there are no memory addresses allowed, except
979
     through indirect addressing, so there are no labels to resolve.  */
980
  p_insn.opcode = p_insn.tm->base_opcode;
981
 
982
  switch (p_insn.tm->oporder)
983
    {
984
    case OO_4op1:
985
      p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
986
      p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
987
      p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
988
      p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
989
      p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
990
      p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 22);
991
      break;
992
 
993
    case OO_4op2:
994
      p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
995
      p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
996
      p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8);
997
      p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11);
998
      p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 19);
999
      p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 22);
1000
      if (p_insn.operand_type[1][1]->reg.opcode == p_insn.operand_type[0][1]->reg.opcode)
1001
        as_warn (_("loading the same register in parallel operation"));
1002
      break;
1003
 
1004
    case OO_4op3:
1005
      p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
1006
      p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
1007
      p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
1008
      p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
1009
      p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1010
      p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 22);
1011
      break;
1012
 
1013
    case OO_5op1:
1014
      p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
1015
      p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
1016
      p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
1017
      p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
1018
      p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1019
      p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
1020
      p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22);
1021
      break;
1022
 
1023
    case OO_5op2:
1024
      p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
1025
      p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
1026
      p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
1027
      p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
1028
      p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1029
      p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19);
1030
      p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22);
1031
      break;
1032
 
1033
    case OO_PField:
1034
      p_insn.opcode |= p_insn.p_field;
1035
      if (p_insn.operand_type[0][2]->reg.opcode == 0x01)
1036
        p_insn.opcode |= 0x00800000;
1037
      if (p_insn.operand_type[1][2]->reg.opcode == 0x03)
1038
        p_insn.opcode |= 0x00400000;
1039
 
1040
      switch (p_insn.p_field)
1041
        {
1042
        case 0x00000000:
1043
          p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
1044
          p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
1045
          p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
1046
          p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
1047
          p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16);
1048
          p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 19);
1049
          break;
1050
        case 0x01000000:
1051
          p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum);
1052
          p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 3);
1053
          p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
1054
          p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
1055
          p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16);
1056
          p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
1057
          break;
1058
        case 0x02000000:
1059
          p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum);
1060
          p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3);
1061
          p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8);
1062
          p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11);
1063
          p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 16);
1064
          p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19);
1065
          break;
1066
        case 0x03000000:
1067
          p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum);
1068
          p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3);
1069
          p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
1070
          p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
1071
          p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1072
          p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
1073
          break;
1074
        }
1075
      break;
1076
    }
1077
 
1078
  {
1079
    char *p;
1080
 
1081
    p = frag_more (INSN_SIZE);
1082
    md_number_to_chars (p, (valueT) p_insn.opcode, INSN_SIZE);
1083
  }
1084
 
1085
  {
1086
    unsigned int i, j;
1087
 
1088
    for (i = 0; i < 2; i++)
1089
      for (j = 0; j < p_insn.operands[i]; j++)
1090
        free (p_insn.operand_type[i][j]);
1091
  }
1092
 
1093
  debug ("Final opcode: %08X\n", p_insn.opcode);
1094
  debug ("\n");
1095
 
1096
  return 1;
1097
}
1098
 
1099
/* In order to get gas to ignore any | chars at the start of a line,
1100
   this function returns true if a | is found in a line.  */
1101
 
1102
int
1103
tic30_unrecognized_line (int c)
1104
{
1105
  debug ("In tc_unrecognized_line\n");
1106
  return (c == PARALLEL_SEPARATOR);
1107
}
1108
 
1109
int
1110
md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
1111
                               segT segment ATTRIBUTE_UNUSED)
1112
{
1113
  debug ("In md_estimate_size_before_relax()\n");
1114
  return 0;
1115
}
1116
 
1117
void
1118
md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
1119
                 segT sec ATTRIBUTE_UNUSED,
1120
                 register fragS *fragP ATTRIBUTE_UNUSED)
1121
{
1122
  debug ("In md_convert_frag()\n");
1123
}
1124
 
1125
void
1126
md_apply_fix (fixS *fixP,
1127
               valueT *valP,
1128
               segT seg ATTRIBUTE_UNUSED)
1129
{
1130
  valueT value = *valP;
1131
 
1132
  debug ("In md_apply_fix() with value = %ld\n", (long) value);
1133
  debug ("Values in fixP\n");
1134
  debug ("fx_size = %d\n", fixP->fx_size);
1135
  debug ("fx_pcrel = %d\n", fixP->fx_pcrel);
1136
  debug ("fx_where = %ld\n", fixP->fx_where);
1137
  debug ("fx_offset = %d\n", (int) fixP->fx_offset);
1138
  {
1139
    char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
1140
 
1141
    value /= INSN_SIZE;
1142
    if (fixP->fx_size == 1)
1143
      /* Special fix for LDP instruction.  */
1144
      value = (value & 0x00FF0000) >> 16;
1145
 
1146
    debug ("new value = %ld\n", (long) value);
1147
    md_number_to_chars (buf, value, fixP->fx_size);
1148
  }
1149
 
1150
  if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
1151
    fixP->fx_done = 1;
1152
}
1153
 
1154
int
1155
md_parse_option (int c ATTRIBUTE_UNUSED,
1156
                 char *arg ATTRIBUTE_UNUSED)
1157
{
1158
  debug ("In md_parse_option()\n");
1159
  return 0;
1160
}
1161
 
1162
void
1163
md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
1164
{
1165
  debug ("In md_show_usage()\n");
1166
}
1167
 
1168
symbolS *
1169
md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
1170
{
1171
  debug ("In md_undefined_symbol()\n");
1172
  return (symbolS *) 0;
1173
}
1174
 
1175
valueT
1176
md_section_align (segT segment, valueT size)
1177
{
1178
  debug ("In md_section_align() segment = %p and size = %lu\n",
1179
         segment, (unsigned long) size);
1180
  size = (size + 3) / 4;
1181
  size *= 4;
1182
  debug ("New size value = %lu\n", (unsigned long) size);
1183
  return size;
1184
}
1185
 
1186
long
1187
md_pcrel_from (fixS *fixP)
1188
{
1189
  int offset;
1190
 
1191
  debug ("In md_pcrel_from()\n");
1192
  debug ("fx_where = %ld\n", fixP->fx_where);
1193
  debug ("fx_size = %d\n", fixP->fx_size);
1194
  /* Find the opcode that represents the current instruction in the
1195
     fr_literal storage area, and check bit 21.  Bit 21 contains whether the
1196
     current instruction is a delayed one or not, and then set the offset
1197
     value appropriately.  */
1198
  if (fixP->fx_frag->fr_literal[fixP->fx_where - fixP->fx_size + 1] & 0x20)
1199
    offset = 3;
1200
  else
1201
    offset = 1;
1202
  debug ("offset = %d\n", offset);
1203
  /* PC Relative instructions have a format:
1204
     displacement = Label - (PC + offset)
1205
     This function returns PC + offset where:
1206
     fx_where - fx_size = PC
1207
     INSN_SIZE * offset = offset number of instructions.  */
1208
  return fixP->fx_where - fixP->fx_size + (INSN_SIZE * offset);
1209
}
1210
 
1211
char *
1212
md_atof (int what_statement_type,
1213
         char *literalP,
1214
         int *sizeP)
1215
{
1216
  int prec;
1217
  char *token;
1218
  char keepval;
1219
  unsigned long value;
1220
  float float_value;
1221
 
1222
  debug ("In md_atof()\n");
1223
  debug ("precision = %c\n", what_statement_type);
1224
  debug ("literal = %s\n", literalP);
1225
  debug ("line = ");
1226
  token = input_line_pointer;
1227
  while (!is_end_of_line[(unsigned char) *input_line_pointer]
1228
         && (*input_line_pointer != ','))
1229
    {
1230
      debug ("%c", *input_line_pointer);
1231
      input_line_pointer++;
1232
    }
1233
 
1234
  keepval = *input_line_pointer;
1235
  *input_line_pointer = '\0';
1236
  debug ("\n");
1237
  float_value = (float) atof (token);
1238
  *input_line_pointer = keepval;
1239
  debug ("float_value = %f\n", float_value);
1240
 
1241
  switch (what_statement_type)
1242
    {
1243
    case 'f':
1244
    case 'F':
1245
    case 's':
1246
    case 'S':
1247
      prec = 2;
1248
      break;
1249
 
1250
    case 'd':
1251
    case 'D':
1252
    case 'r':
1253
    case 'R':
1254
      prec = 4;
1255
      break;
1256
 
1257
    default:
1258
      *sizeP = 0;
1259
      return _("Unrecognized or unsupported floating point constant");
1260
    }
1261
 
1262
  if (float_value == 0.0)
1263
    value = (prec == 2) ? 0x00008000L : 0x80000000L;
1264
  else
1265
    {
1266
      unsigned long exp, sign, mant, tmsfloat;
1267
      union
1268
      {
1269
        float f;
1270
        long  l;
1271
      }
1272
      converter;
1273
 
1274
      converter.f = float_value;
1275
      tmsfloat = converter.l;
1276
      sign = tmsfloat & 0x80000000;
1277
      mant = tmsfloat & 0x007FFFFF;
1278
      exp = tmsfloat & 0x7F800000;
1279
      exp <<= 1;
1280
      if (exp == 0xFF000000)
1281
        {
1282
          if (mant == 0)
1283
            value = 0x7F7FFFFF;
1284
          else if (sign == 0)
1285
            value = 0x7F7FFFFF;
1286
          else
1287
            value = 0x7F800000;
1288
        }
1289
      else
1290
        {
1291
          exp -= 0x7F000000;
1292
          if (sign)
1293
            {
1294
              mant = mant & 0x007FFFFF;
1295
              mant = -mant;
1296
              mant = mant & 0x00FFFFFF;
1297
              if (mant == 0)
1298
                {
1299
                  mant |= 0x00800000;
1300
                  exp = (long) exp - 0x01000000;
1301
                }
1302
            }
1303
          tmsfloat = exp | mant;
1304
          value = tmsfloat;
1305
        }
1306
      if (prec == 2)
1307
        {
1308
          long expon, mantis;
1309
 
1310
          if (tmsfloat == 0x80000000)
1311
            value = 0x8000;
1312
          else
1313
            {
1314
              value = 0;
1315
              expon = (tmsfloat & 0xFF000000);
1316
              expon >>= 24;
1317
              mantis = tmsfloat & 0x007FFFFF;
1318
              if (tmsfloat & 0x00800000)
1319
                {
1320
                  mantis |= 0xFF000000;
1321
                  mantis += 0x00000800;
1322
                  mantis >>= 12;
1323
                  mantis |= 0x00000800;
1324
                  mantis &= 0x0FFF;
1325
                  if (expon > 7)
1326
                    value = 0x7800;
1327
                }
1328
              else
1329
                {
1330
                  mantis |= 0x00800000;
1331
                  mantis += 0x00000800;
1332
                  expon += (mantis >> 24);
1333
                  mantis >>= 12;
1334
                  mantis &= 0x07FF;
1335
                  if (expon > 7)
1336
                    value = 0x77FF;
1337
                }
1338
              if (expon < -8)
1339
                value = 0x8000;
1340
              if (value == 0)
1341
                {
1342
                  mantis = (expon << 12) | mantis;
1343
                  value = mantis & 0xFFFF;
1344
                }
1345
            }
1346
        }
1347
    }
1348
  md_number_to_chars (literalP, value, prec);
1349
  *sizeP = prec;
1350
  return NULL;
1351
}
1352
 
1353
void
1354
md_number_to_chars (char *buf, valueT val, int n)
1355
{
1356
  debug ("In md_number_to_chars()\n");
1357
  number_to_chars_bigendian (buf, val, n);
1358
}
1359
 
1360
#define F(SZ,PCREL)             (((SZ) << 1) + (PCREL))
1361
#define MAP(SZ,PCREL,TYPE)      case F(SZ,PCREL): code = (TYPE); break
1362
 
1363
arelent *
1364
tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
1365
{
1366
  arelent *rel;
1367
  bfd_reloc_code_real_type code = 0;
1368
 
1369
  debug ("In tc_gen_reloc()\n");
1370
  debug ("fixP.size = %d\n", fixP->fx_size);
1371
  debug ("fixP.pcrel = %d\n", fixP->fx_pcrel);
1372
  debug ("addsy.name = %s\n", S_GET_NAME (fixP->fx_addsy));
1373
 
1374
  switch (F (fixP->fx_size, fixP->fx_pcrel))
1375
    {
1376
      MAP (1, 0, BFD_RELOC_TIC30_LDP);
1377
      MAP (2, 0, BFD_RELOC_16);
1378
      MAP (3, 0, BFD_RELOC_24);
1379
      MAP (2, 1, BFD_RELOC_16_PCREL);
1380
      MAP (4, 0, BFD_RELOC_32);
1381
    default:
1382
      as_bad (_("Can not do %d byte %srelocation"), fixP->fx_size,
1383
              fixP->fx_pcrel ? _("pc-relative ") : "");
1384
    }
1385
#undef MAP
1386
#undef F
1387
 
1388
  rel = xmalloc (sizeof (* rel));
1389
  gas_assert (rel != 0);
1390
  rel->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
1391
  *rel->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
1392
  rel->address = fixP->fx_frag->fr_address + fixP->fx_where;
1393
  rel->addend = 0;
1394
  rel->howto = bfd_reloc_type_lookup (stdoutput, code);
1395
  if (!rel->howto)
1396
    {
1397
      const char *name;
1398
 
1399
      name = S_GET_NAME (fixP->fx_addsy);
1400
      if (name == NULL)
1401
        name = "<unknown>";
1402
      as_fatal ("Cannot generate relocation type for symbol %s, code %s",
1403
                name, bfd_get_reloc_code_name (code));
1404
    }
1405
  return rel;
1406
}
1407
 
1408
void
1409
md_operand (expressionS *expressionP ATTRIBUTE_UNUSED)
1410
{
1411
  debug ("In md_operand()\n");
1412
}
1413
 
1414
void
1415
md_assemble (char *line)
1416
{
1417
  insn_template *op;
1418
  char *current_posn;
1419
  char *token_start;
1420
  char save_char;
1421
  unsigned int count;
1422
 
1423
  debug ("In md_assemble() with argument %s\n", line);
1424
  memset (&insn, '\0', sizeof (insn));
1425
  if (found_parallel_insn)
1426
    {
1427
      debug ("Line is second part of parallel instruction\n\n");
1428
      found_parallel_insn = 0;
1429
      return;
1430
    }
1431
  if ((current_posn =
1432
       tic30_find_parallel_insn (line, input_line_pointer + 1)) == NULL)
1433
    current_posn = line;
1434
  else
1435
    found_parallel_insn = 1;
1436
 
1437
  while (is_space_char (*current_posn))
1438
    current_posn++;
1439
 
1440
  token_start = current_posn;
1441
 
1442
  if (!is_opcode_char (*current_posn))
1443
    {
1444
      as_bad (_("Invalid character %s in opcode"),
1445
              output_invalid (*current_posn));
1446
      return;
1447
    }
1448
  /* Check if instruction is a parallel instruction
1449
     by seeing if the first character is a q.  */
1450
  if (*token_start == 'q')
1451
    {
1452
      if (tic30_parallel_insn (token_start))
1453
        {
1454
          if (found_parallel_insn)
1455
            free (token_start);
1456
          return;
1457
        }
1458
    }
1459
  while (is_opcode_char (*current_posn))
1460
    current_posn++;
1461
  {
1462
    /* Find instruction.  */
1463
    save_char = *current_posn;
1464
    *current_posn = '\0';
1465
    op = (insn_template *) hash_find (op_hash, token_start);
1466
    if (op)
1467
      {
1468
        debug ("Found instruction %s\n", op->name);
1469
        insn.tm = op;
1470
      }
1471
    else
1472
      {
1473
        debug ("Didn't find insn\n");
1474
        as_bad (_("Unknown TMS320C30 instruction: %s"), token_start);
1475
        return;
1476
      }
1477
    *current_posn = save_char;
1478
  }
1479
 
1480
  if (*current_posn != END_OF_INSN)
1481
    {
1482
      /* Find operands.  */
1483
      int paren_not_balanced;
1484
      int expecting_operand = 0;
1485
      int this_operand;
1486
      do
1487
        {
1488
          /* Skip optional white space before operand.  */
1489
          while (!is_operand_char (*current_posn)
1490
                 && *current_posn != END_OF_INSN)
1491
            {
1492
              if (!is_space_char (*current_posn))
1493
                {
1494
                  as_bad (_("Invalid character %s before %s operand"),
1495
                          output_invalid (*current_posn),
1496
                          ordinal_names[insn.operands]);
1497
                  return;
1498
                }
1499
              current_posn++;
1500
            }
1501
          token_start = current_posn;
1502
          paren_not_balanced = 0;
1503
          while (paren_not_balanced || *current_posn != ',')
1504
            {
1505
              if (*current_posn == END_OF_INSN)
1506
                {
1507
                  if (paren_not_balanced)
1508
                    {
1509
                      as_bad (_("Unbalanced parenthesis in %s operand."),
1510
                              ordinal_names[insn.operands]);
1511
                      return;
1512
                    }
1513
                  else
1514
                    break;
1515
                }
1516
              else if (!is_operand_char (*current_posn)
1517
                       && !is_space_char (*current_posn))
1518
                {
1519
                  as_bad (_("Invalid character %s in %s operand"),
1520
                          output_invalid (*current_posn),
1521
                          ordinal_names[insn.operands]);
1522
                  return;
1523
                }
1524
              if (*current_posn == '(')
1525
                ++paren_not_balanced;
1526
              if (*current_posn == ')')
1527
                --paren_not_balanced;
1528
              current_posn++;
1529
            }
1530
          if (current_posn != token_start)
1531
            {
1532
              /* Yes, we've read in another operand.  */
1533
              this_operand = insn.operands++;
1534
              if (insn.operands > MAX_OPERANDS)
1535
                {
1536
                  as_bad (_("Spurious operands; (%d operands/instruction max)"),
1537
                          MAX_OPERANDS);
1538
                  return;
1539
                }
1540
 
1541
              /* Now parse operand adding info to 'insn' as we go along.  */
1542
              save_char = *current_posn;
1543
              *current_posn = '\0';
1544
              insn.operand_type[this_operand] = tic30_operand (token_start);
1545
              *current_posn = save_char;
1546
              if (insn.operand_type[this_operand] == NULL)
1547
                return;
1548
            }
1549
          else
1550
            {
1551
              if (expecting_operand)
1552
                {
1553
                  as_bad (_("Expecting operand after ','; got nothing"));
1554
                  return;
1555
                }
1556
              if (*current_posn == ',')
1557
                {
1558
                  as_bad (_("Expecting operand before ','; got nothing"));
1559
                  return;
1560
                }
1561
            }
1562
 
1563
          /* Now *current_posn must be either ',' or END_OF_INSN.  */
1564
          if (*current_posn == ',')
1565
            {
1566
              if (*++current_posn == END_OF_INSN)
1567
                {
1568
                  /* Just skip it, if it's \n complain.  */
1569
                  as_bad (_("Expecting operand after ','; got nothing"));
1570
                  return;
1571
                }
1572
              expecting_operand = 1;
1573
            }
1574
        }
1575
      while (*current_posn != END_OF_INSN);
1576
    }
1577
 
1578
  debug ("Number of operands found: %d\n", insn.operands);
1579
 
1580
  /* Check that number of operands is correct.  */
1581
  if (insn.operands != insn.tm->operands)
1582
    {
1583
      unsigned int i;
1584
      unsigned int numops = insn.tm->operands;
1585
 
1586
      /* If operands are not the same, then see if any of the operands are
1587
         not required.  Then recheck with number of given operands.  If they
1588
         are still not the same, then give an error, otherwise carry on.  */
1589
      for (i = 0; i < insn.tm->operands; i++)
1590
        if (insn.tm->operand_types[i] & NotReq)
1591
          numops--;
1592
      if (insn.operands != numops)
1593
        {
1594
          as_bad (_("Incorrect number of operands given"));
1595
          return;
1596
        }
1597
    }
1598
  insn.addressing_mode = AM_NotReq;
1599
  for (count = 0; count < insn.operands; count++)
1600
    {
1601
      if (insn.operand_type[count]->op_type & insn.tm->operand_types[count])
1602
        {
1603
          debug ("Operand %d matches\n", count + 1);
1604
          /* If instruction has two operands and has an AddressMode
1605
             modifier then set addressing mode type for instruction.  */
1606
          if (insn.tm->opcode_modifier == AddressMode)
1607
            {
1608
              int addr_insn = 0;
1609
              /* Store instruction uses the second
1610
                 operand for the address mode.  */
1611
              if ((insn.tm->operand_types[1] & (Indirect | Direct))
1612
                  == (Indirect | Direct))
1613
                addr_insn = 1;
1614
 
1615
              if (insn.operand_type[addr_insn]->op_type & (AllReg))
1616
                insn.addressing_mode = AM_Register;
1617
              else if (insn.operand_type[addr_insn]->op_type & Direct)
1618
                insn.addressing_mode = AM_Direct;
1619
              else if (insn.operand_type[addr_insn]->op_type & Indirect)
1620
                insn.addressing_mode = AM_Indirect;
1621
              else
1622
                insn.addressing_mode = AM_Immediate;
1623
            }
1624
        }
1625
      else
1626
        {
1627
          as_bad (_("The %s operand doesn't match"), ordinal_names[count]);
1628
          return;
1629
        }
1630
    }
1631
 
1632
  /* Now set the addressing mode for 3 operand instructions.  */
1633
  if ((insn.tm->operand_types[0] & op3T1)
1634
      && (insn.tm->operand_types[1] & op3T2))
1635
    {
1636
      /* Set the addressing mode to the values used for 2 operand
1637
         instructions in the  G addressing field of the opcode.  */
1638
      char *p;
1639
      switch (insn.operand_type[0]->op_type)
1640
        {
1641
        case Rn:
1642
        case ARn:
1643
        case DPReg:
1644
        case OtherReg:
1645
          if (insn.operand_type[1]->op_type & (AllReg))
1646
            insn.addressing_mode = AM_Register;
1647
          else if (insn.operand_type[1]->op_type & Indirect)
1648
            insn.addressing_mode = AM_Direct;
1649
          else
1650
            {
1651
              /* Shouldn't make it to this stage.  */
1652
              as_bad (_("Incompatible first and second operands in instruction"));
1653
              return;
1654
            }
1655
          break;
1656
        case Indirect:
1657
          if (insn.operand_type[1]->op_type & (AllReg))
1658
            insn.addressing_mode = AM_Indirect;
1659
          else if (insn.operand_type[1]->op_type & Indirect)
1660
            insn.addressing_mode = AM_Immediate;
1661
          else
1662
            {
1663
              /* Shouldn't make it to this stage.  */
1664
              as_bad (_("Incompatible first and second operands in instruction"));
1665
              return;
1666
            }
1667
          break;
1668
        }
1669
      /* Now make up the opcode for the 3 operand instructions.  As in
1670
         parallel instructions, there will be no unresolved values, so they
1671
         can be fully formed and added to the frag table.  */
1672
      insn.opcode = insn.tm->base_opcode;
1673
      if (insn.operand_type[0]->op_type & Indirect)
1674
        {
1675
          insn.opcode |= (insn.operand_type[0]->indirect.ARnum);
1676
          insn.opcode |= (insn.operand_type[0]->indirect.mod << 3);
1677
        }
1678
      else
1679
        insn.opcode |= (insn.operand_type[0]->reg.opcode);
1680
 
1681
      if (insn.operand_type[1]->op_type & Indirect)
1682
        {
1683
          insn.opcode |= (insn.operand_type[1]->indirect.ARnum << 8);
1684
          insn.opcode |= (insn.operand_type[1]->indirect.mod << 11);
1685
        }
1686
      else
1687
        insn.opcode |= (insn.operand_type[1]->reg.opcode << 8);
1688
 
1689
      if (insn.operands == 3)
1690
        insn.opcode |= (insn.operand_type[2]->reg.opcode << 16);
1691
 
1692
      insn.opcode |= insn.addressing_mode;
1693
      p = frag_more (INSN_SIZE);
1694
      md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1695
    }
1696
  else
1697
    {
1698
      /* Not a three operand instruction.  */
1699
      char *p;
1700
      int am_insn = -1;
1701
      insn.opcode = insn.tm->base_opcode;
1702
      /* Create frag for instruction - all instructions are 4 bytes long.  */
1703
      p = frag_more (INSN_SIZE);
1704
      if ((insn.operands > 0) && (insn.tm->opcode_modifier == AddressMode))
1705
        {
1706
          insn.opcode |= insn.addressing_mode;
1707
          if (insn.addressing_mode == AM_Indirect)
1708
            {
1709
              /* Determine which operand gives the addressing mode.  */
1710
              if (insn.operand_type[0]->op_type & Indirect)
1711
                am_insn = 0;
1712
              if ((insn.operands > 1)
1713
                  && (insn.operand_type[1]->op_type & Indirect))
1714
                am_insn = 1;
1715
              insn.opcode |= (insn.operand_type[am_insn]->indirect.disp);
1716
              insn.opcode |= (insn.operand_type[am_insn]->indirect.ARnum << 8);
1717
              insn.opcode |= (insn.operand_type[am_insn]->indirect.mod << 11);
1718
              if (insn.operands > 1)
1719
                insn.opcode |= (insn.operand_type[!am_insn]->reg.opcode << 16);
1720
              md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1721
            }
1722
          else if (insn.addressing_mode == AM_Register)
1723
            {
1724
              insn.opcode |= (insn.operand_type[0]->reg.opcode);
1725
              if (insn.operands > 1)
1726
                insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
1727
              md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1728
            }
1729
          else if (insn.addressing_mode == AM_Direct)
1730
            {
1731
              if (insn.operand_type[0]->op_type & Direct)
1732
                am_insn = 0;
1733
              if ((insn.operands > 1)
1734
                  && (insn.operand_type[1]->op_type & Direct))
1735
                am_insn = 1;
1736
              if (insn.operands > 1)
1737
                insn.opcode |=
1738
                  (insn.operand_type[! am_insn]->reg.opcode << 16);
1739
              if (insn.operand_type[am_insn]->direct.resolved == 1)
1740
                {
1741
                  /* Resolved values can be placed straight
1742
                     into instruction word, and output.  */
1743
                  insn.opcode |=
1744
                    (insn.operand_type[am_insn]->direct.address & 0x0000FFFF);
1745
                  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1746
                }
1747
              else
1748
                {
1749
                  /* Unresolved direct addressing mode instruction.  */
1750
                  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1751
                  fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2,
1752
                               & insn.operand_type[am_insn]->direct.direct_expr,
1753
                               0, 0);
1754
                }
1755
            }
1756
          else if (insn.addressing_mode == AM_Immediate)
1757
            {
1758
              if (insn.operand_type[0]->immediate.resolved == 1)
1759
                {
1760
                  char *keeploc;
1761
                  int size;
1762
 
1763
                  if (insn.operands > 1)
1764
                    insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
1765
 
1766
                  switch (insn.tm->imm_arg_type)
1767
                    {
1768
                    case Imm_Float:
1769
                      debug ("Floating point first operand\n");
1770
                      md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1771
 
1772
                      keeploc = input_line_pointer;
1773
                      input_line_pointer =
1774
                        insn.operand_type[0]->immediate.label;
1775
 
1776
                      if (md_atof ('f', p + 2, & size) != 0)
1777
                        {
1778
                          as_bad (_("invalid short form floating point immediate operand"));
1779
                          return;
1780
                        }
1781
 
1782
                      input_line_pointer = keeploc;
1783
                      break;
1784
 
1785
                    case Imm_UInt:
1786
                      debug ("Unsigned int first operand\n");
1787
                      if (insn.operand_type[0]->immediate.decimal_found)
1788
                        as_warn (_("rounding down first operand float to unsigned int"));
1789
                      if (insn.operand_type[0]->immediate.u_number > 0xFFFF)
1790
                        as_warn (_("only lower 16-bits of first operand are used"));
1791
                      insn.opcode |=
1792
                        (insn.operand_type[0]->immediate.u_number & 0x0000FFFFL);
1793
                      md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1794
                      break;
1795
 
1796
                    case Imm_SInt:
1797
                      debug ("Int first operand\n");
1798
 
1799
                      if (insn.operand_type[0]->immediate.decimal_found)
1800
                        as_warn (_("rounding down first operand float to signed int"));
1801
 
1802
                      if (insn.operand_type[0]->immediate.s_number < -32768 ||
1803
                          insn.operand_type[0]->immediate.s_number > 32767)
1804
                        {
1805
                          as_bad (_("first operand is too large for 16-bit signed int"));
1806
                          return;
1807
                        }
1808
                      insn.opcode |=
1809
                        (insn.operand_type[0]->immediate.s_number & 0x0000FFFFL);
1810
                      md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1811
                      break;
1812
                    }
1813
                }
1814
              else
1815
                {
1816
                  /* Unresolved immediate label.  */
1817
                  if (insn.operands > 1)
1818
                    insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
1819
                  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1820
                  fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2,
1821
                               & insn.operand_type[0]->immediate.imm_expr,
1822
                               0, 0);
1823
                }
1824
            }
1825
        }
1826
      else if (insn.tm->opcode_modifier == PCRel)
1827
        {
1828
          /* Conditional Branch and Call instructions.  */
1829
          if ((insn.tm->operand_types[0] & (AllReg | Disp))
1830
              == (AllReg | Disp))
1831
            {
1832
              if (insn.operand_type[0]->op_type & (AllReg))
1833
                {
1834
                  insn.opcode |= (insn.operand_type[0]->reg.opcode);
1835
                  insn.opcode |= PC_Register;
1836
                  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1837
                }
1838
              else
1839
                {
1840
                  insn.opcode |= PC_Relative;
1841
                  if (insn.operand_type[0]->immediate.resolved == 1)
1842
                    {
1843
                      insn.opcode |=
1844
                        (insn.operand_type[0]->immediate.s_number & 0x0000FFFF);
1845
                      md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1846
                    }
1847
                  else
1848
                    {
1849
                      md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1850
                      fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal),
1851
                                   2, & insn.operand_type[0]->immediate.imm_expr,
1852
                                   1, 0);
1853
                    }
1854
                }
1855
            }
1856
          else if ((insn.tm->operand_types[0] & ARn) == ARn)
1857
            {
1858
              /* Decrement and Branch instructions.  */
1859
              insn.opcode |= ((insn.operand_type[0]->reg.opcode - 0x08) << 22);
1860
              if (insn.operand_type[1]->op_type & (AllReg))
1861
                {
1862
                  insn.opcode |= (insn.operand_type[1]->reg.opcode);
1863
                  insn.opcode |= PC_Register;
1864
                  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1865
                }
1866
              else if (insn.operand_type[1]->immediate.resolved == 1)
1867
                {
1868
                  if (insn.operand_type[0]->immediate.decimal_found)
1869
                    {
1870
                      as_bad (_("first operand is floating point"));
1871
                      return;
1872
                    }
1873
                  if (insn.operand_type[0]->immediate.s_number < -32768 ||
1874
                      insn.operand_type[0]->immediate.s_number > 32767)
1875
                    {
1876
                      as_bad (_("first operand is too large for 16-bit signed int"));
1877
                      return;
1878
                    }
1879
                  insn.opcode |= (insn.operand_type[1]->immediate.s_number);
1880
                  insn.opcode |= PC_Relative;
1881
                  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1882
                }
1883
              else
1884
                {
1885
                  insn.opcode |= PC_Relative;
1886
                  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1887
                  fix_new_exp (frag_now, p + 2 - frag_now->fr_literal, 2,
1888
                               & insn.operand_type[1]->immediate.imm_expr,
1889
                               1, 0);
1890
                }
1891
            }
1892
        }
1893
      else if (insn.tm->operand_types[0] == IVector)
1894
        {
1895
          /* Trap instructions.  */
1896
          if (insn.operand_type[0]->op_type & IVector)
1897
            insn.opcode |= (insn.operand_type[0]->immediate.u_number);
1898
          else
1899
            {
1900
              /* Shouldn't get here.  */
1901
              as_bad (_("interrupt vector for trap instruction out of range"));
1902
              return;
1903
            }
1904
          md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1905
        }
1906
      else if (insn.tm->opcode_modifier == StackOp
1907
               || insn.tm->opcode_modifier == Rotate)
1908
        {
1909
          /* Push, Pop and Rotate instructions.  */
1910
          insn.opcode |= (insn.operand_type[0]->reg.opcode << 16);
1911
          md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1912
        }
1913
      else if ((insn.tm->operand_types[0] & (Abs24 | Direct))
1914
               == (Abs24 | Direct))
1915
        {
1916
          /* LDP Instruction needs to be tested
1917
             for before the next section.  */
1918
          if (insn.operand_type[0]->op_type & Direct)
1919
            {
1920
              if (insn.operand_type[0]->direct.resolved == 1)
1921
                {
1922
                  /* Direct addressing uses lower 8 bits of direct address.  */
1923
                  insn.opcode |=
1924
                    (insn.operand_type[0]->direct.address & 0x00FF0000) >> 16;
1925
                  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1926
                }
1927
              else
1928
                {
1929
                  fixS *fix;
1930
 
1931
                  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1932
                  fix = fix_new_exp (frag_now, p + 3 - (frag_now->fr_literal),
1933
                                     1, &insn.operand_type[0]->direct.direct_expr, 0, 0);
1934
                  /* Ensure that the assembler doesn't complain
1935
                     about fitting a 24-bit address into 8 bits.  */
1936
                  fix->fx_no_overflow = 1;
1937
                }
1938
            }
1939
          else
1940
            {
1941
              if (insn.operand_type[0]->immediate.resolved == 1)
1942
                {
1943
                  /* Immediate addressing uses upper 8 bits of address.  */
1944
                  if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF)
1945
                    {
1946
                      as_bad (_("LDP instruction needs a 24-bit operand"));
1947
                      return;
1948
                    }
1949
                  insn.opcode |=
1950
                    ((insn.operand_type[0]->immediate.u_number & 0x00FF0000) >> 16);
1951
                  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1952
                }
1953
              else
1954
                {
1955
                  fixS *fix;
1956
                  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1957
                  fix = fix_new_exp (frag_now, p + 3 - (frag_now->fr_literal),
1958
                                     1, &insn.operand_type[0]->immediate.imm_expr,
1959
                                     0, 0);
1960
                  fix->fx_no_overflow = 1;
1961
                }
1962
            }
1963
        }
1964
      else if (insn.tm->operand_types[0] & (Imm24))
1965
        {
1966
          /* Unconditional Branch and Call instructions.  */
1967
          if (insn.operand_type[0]->immediate.resolved == 1)
1968
            {
1969
              if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF)
1970
                as_warn (_("first operand is too large for a 24-bit displacement"));
1971
              insn.opcode |=
1972
                (insn.operand_type[0]->immediate.u_number & 0x00FFFFFF);
1973
              md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1974
            }
1975
          else
1976
            {
1977
              md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1978
              fix_new_exp (frag_now, p + 1 - (frag_now->fr_literal), 3,
1979
                           & insn.operand_type[0]->immediate.imm_expr, 0, 0);
1980
            }
1981
        }
1982
      else if (insn.tm->operand_types[0] & NotReq)
1983
        /* Check for NOP instruction without arguments.  */
1984
        md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1985
 
1986
      else if (insn.tm->operands == 0)
1987
        /* Check for instructions without operands.  */
1988
        md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1989
    }
1990
  debug ("Addressing mode: %08X\n", insn.addressing_mode);
1991
  {
1992
    unsigned int i;
1993
 
1994
    for (i = 0; i < insn.operands; i++)
1995
      {
1996
        if (insn.operand_type[i]->immediate.label)
1997
          free (insn.operand_type[i]->immediate.label);
1998
        free (insn.operand_type[i]);
1999
      }
2000
  }
2001
  debug ("Final opcode: %08X\n", insn.opcode);
2002
  debug ("\n");
2003
}

powered by: WebSVN 2.1.0

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