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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-binutils/] [binutils-2.19.1/] [gas/] [config/] [tc-bfin.c] - Blame information for rev 6

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 6 jlechner
/* tc-bfin.c -- Assembler for the ADI Blackfin.
2
   Copyright 2005, 2006, 2007, 2008
3
   Free Software Foundation, Inc.
4
 
5
   This file is part of GAS, the GNU Assembler.
6
 
7
   GAS is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 3, or (at your option)
10
   any later version.
11
 
12
   GAS is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
 
17
   You should have received a copy of the GNU General Public License
18
   along with GAS; see the file COPYING.  If not, write to the Free
19
   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
20
   02110-1301, USA.  */
21
 
22
#include "as.h"
23
#include "struc-symbol.h"
24
#include "bfin-defs.h"
25
#include "obstack.h"
26
#include "safe-ctype.h"
27
#ifdef OBJ_ELF
28
#include "dwarf2dbg.h"
29
#endif
30
#include "libbfd.h"
31
#include "elf/common.h"
32
#include "elf/bfin.h"
33
 
34
extern int yyparse (void);
35
struct yy_buffer_state;
36
typedef struct yy_buffer_state *YY_BUFFER_STATE;
37
extern YY_BUFFER_STATE yy_scan_string (const char *yy_str);
38
extern void yy_delete_buffer (YY_BUFFER_STATE b);
39
static parse_state parse (char *line);
40
 
41
/* Global variables. */
42
struct bfin_insn *insn;
43
int last_insn_size;
44
 
45
extern struct obstack mempool;
46
FILE *errorf;
47
 
48
/* Flags to set in the elf header */
49
#define DEFAULT_FLAGS 0
50
 
51
#ifdef OBJ_FDPIC_ELF
52
# define DEFAULT_FDPIC EF_BFIN_FDPIC
53
#else
54
# define DEFAULT_FDPIC 0
55
#endif
56
 
57
static flagword bfin_flags = DEFAULT_FLAGS | DEFAULT_FDPIC;
58
static const char *bfin_pic_flag = DEFAULT_FDPIC ? "-mfdpic" : (const char *)0;
59
 
60
/* Registers list.  */
61
struct bfin_reg_entry
62
{
63
  const char *name;
64
  int number;
65
};
66
 
67
static const struct bfin_reg_entry bfin_reg_info[] = {
68
  {"R0.L", REG_RL0},
69
  {"R1.L", REG_RL1},
70
  {"R2.L", REG_RL2},
71
  {"R3.L", REG_RL3},
72
  {"R4.L", REG_RL4},
73
  {"R5.L", REG_RL5},
74
  {"R6.L", REG_RL6},
75
  {"R7.L", REG_RL7},
76
  {"R0.H", REG_RH0},
77
  {"R1.H", REG_RH1},
78
  {"R2.H", REG_RH2},
79
  {"R3.H", REG_RH3},
80
  {"R4.H", REG_RH4},
81
  {"R5.H", REG_RH5},
82
  {"R6.H", REG_RH6},
83
  {"R7.H", REG_RH7},
84
  {"R0", REG_R0},
85
  {"R1", REG_R1},
86
  {"R2", REG_R2},
87
  {"R3", REG_R3},
88
  {"R4", REG_R4},
89
  {"R5", REG_R5},
90
  {"R6", REG_R6},
91
  {"R7", REG_R7},
92
  {"P0", REG_P0},
93
  {"P0.H", REG_P0},
94
  {"P0.L", REG_P0},
95
  {"P1", REG_P1},
96
  {"P1.H", REG_P1},
97
  {"P1.L", REG_P1},
98
  {"P2", REG_P2},
99
  {"P2.H", REG_P2},
100
  {"P2.L", REG_P2},
101
  {"P3", REG_P3},
102
  {"P3.H", REG_P3},
103
  {"P3.L", REG_P3},
104
  {"P4", REG_P4},
105
  {"P4.H", REG_P4},
106
  {"P4.L", REG_P4},
107
  {"P5", REG_P5},
108
  {"P5.H", REG_P5},
109
  {"P5.L", REG_P5},
110
  {"SP", REG_SP},
111
  {"SP.L", REG_SP},
112
  {"SP.H", REG_SP},
113
  {"FP", REG_FP},
114
  {"FP.L", REG_FP},
115
  {"FP.H", REG_FP},
116
  {"A0x", REG_A0x},
117
  {"A1x", REG_A1x},
118
  {"A0w", REG_A0w},
119
  {"A1w", REG_A1w},
120
  {"A0.x", REG_A0x},
121
  {"A1.x", REG_A1x},
122
  {"A0.w", REG_A0w},
123
  {"A1.w", REG_A1w},
124
  {"A0", REG_A0},
125
  {"A0.L", REG_A0},
126
  {"A0.H", REG_A0},
127
  {"A1", REG_A1},
128
  {"A1.L", REG_A1},
129
  {"A1.H", REG_A1},
130
  {"I0", REG_I0},
131
  {"I0.L", REG_I0},
132
  {"I0.H", REG_I0},
133
  {"I1", REG_I1},
134
  {"I1.L", REG_I1},
135
  {"I1.H", REG_I1},
136
  {"I2", REG_I2},
137
  {"I2.L", REG_I2},
138
  {"I2.H", REG_I2},
139
  {"I3", REG_I3},
140
  {"I3.L", REG_I3},
141
  {"I3.H", REG_I3},
142
  {"M0", REG_M0},
143
  {"M0.H", REG_M0},
144
  {"M0.L", REG_M0},
145
  {"M1", REG_M1},
146
  {"M1.H", REG_M1},
147
  {"M1.L", REG_M1},
148
  {"M2", REG_M2},
149
  {"M2.H", REG_M2},
150
  {"M2.L", REG_M2},
151
  {"M3", REG_M3},
152
  {"M3.H", REG_M3},
153
  {"M3.L", REG_M3},
154
  {"B0", REG_B0},
155
  {"B0.H", REG_B0},
156
  {"B0.L", REG_B0},
157
  {"B1", REG_B1},
158
  {"B1.H", REG_B1},
159
  {"B1.L", REG_B1},
160
  {"B2", REG_B2},
161
  {"B2.H", REG_B2},
162
  {"B2.L", REG_B2},
163
  {"B3", REG_B3},
164
  {"B3.H", REG_B3},
165
  {"B3.L", REG_B3},
166
  {"L0", REG_L0},
167
  {"L0.H", REG_L0},
168
  {"L0.L", REG_L0},
169
  {"L1", REG_L1},
170
  {"L1.H", REG_L1},
171
  {"L1.L", REG_L1},
172
  {"L2", REG_L2},
173
  {"L2.H", REG_L2},
174
  {"L2.L", REG_L2},
175
  {"L3", REG_L3},
176
  {"L3.H", REG_L3},
177
  {"L3.L", REG_L3},
178
  {"AZ", S_AZ},
179
  {"AN", S_AN},
180
  {"AC0", S_AC0},
181
  {"AC1", S_AC1},
182
  {"AV0", S_AV0},
183
  {"AV0S", S_AV0S},
184
  {"AV1", S_AV1},
185
  {"AV1S", S_AV1S},
186
  {"AQ", S_AQ},
187
  {"V", S_V},
188
  {"VS", S_VS},
189
  {"sftreset", REG_sftreset},
190
  {"omode", REG_omode},
191
  {"excause", REG_excause},
192
  {"emucause", REG_emucause},
193
  {"idle_req", REG_idle_req},
194
  {"hwerrcause", REG_hwerrcause},
195
  {"CC", REG_CC},
196
  {"LC0", REG_LC0},
197
  {"LC1", REG_LC1},
198
  {"ASTAT", REG_ASTAT},
199
  {"RETS", REG_RETS},
200
  {"LT0", REG_LT0},
201
  {"LB0", REG_LB0},
202
  {"LT1", REG_LT1},
203
  {"LB1", REG_LB1},
204
  {"CYCLES", REG_CYCLES},
205
  {"CYCLES2", REG_CYCLES2},
206
  {"USP", REG_USP},
207
  {"SEQSTAT", REG_SEQSTAT},
208
  {"SYSCFG", REG_SYSCFG},
209
  {"RETI", REG_RETI},
210
  {"RETX", REG_RETX},
211
  {"RETN", REG_RETN},
212
  {"RETE", REG_RETE},
213
  {"EMUDAT", REG_EMUDAT},
214
  {0, 0}
215
};
216
 
217
/* Blackfin specific function to handle FD-PIC pointer initializations.  */
218
 
219
static void
220
bfin_pic_ptr (int nbytes)
221
{
222
  expressionS exp;
223
  char *p;
224
 
225
  if (nbytes != 4)
226
    abort ();
227
 
228
#ifdef md_flush_pending_output
229
  md_flush_pending_output ();
230
#endif
231
 
232
  if (is_it_end_of_statement ())
233
    {
234
      demand_empty_rest_of_line ();
235
      return;
236
    }
237
 
238
#ifdef md_cons_align
239
  md_cons_align (nbytes);
240
#endif
241
 
242
  do
243
    {
244
      bfd_reloc_code_real_type reloc_type = BFD_RELOC_BFIN_FUNCDESC;
245
 
246
      if (strncasecmp (input_line_pointer, "funcdesc(", 9) == 0)
247
        {
248
          input_line_pointer += 9;
249
          expression (&exp);
250
          if (*input_line_pointer == ')')
251
            input_line_pointer++;
252
          else
253
            as_bad (_("missing ')'"));
254
        }
255
      else
256
        error ("missing funcdesc in picptr");
257
 
258
      p = frag_more (4);
259
      memset (p, 0, 4);
260
      fix_new_exp (frag_now, p - frag_now->fr_literal, 4, &exp, 0,
261
                   reloc_type);
262
    }
263
  while (*input_line_pointer++ == ',');
264
 
265
  input_line_pointer--;                 /* Put terminator back into stream. */
266
  demand_empty_rest_of_line ();
267
}
268
 
269
static void
270
bfin_s_bss (int ignore ATTRIBUTE_UNUSED)
271
{
272
  register int temp;
273
 
274
  temp = get_absolute_expression ();
275
  subseg_set (bss_section, (subsegT) temp);
276
  demand_empty_rest_of_line ();
277
}
278
 
279
const pseudo_typeS md_pseudo_table[] = {
280
  {"align", s_align_bytes, 0},
281
  {"byte2", cons, 2},
282
  {"byte4", cons, 4},
283
  {"picptr", bfin_pic_ptr, 4},
284
  {"code", obj_elf_section, 0},
285
  {"db", cons, 1},
286
  {"dd", cons, 4},
287
  {"dw", cons, 2},
288
  {"p", s_ignore, 0},
289
  {"pdata", s_ignore, 0},
290
  {"var", s_ignore, 0},
291
  {"bss", bfin_s_bss, 0},
292
  {0, 0, 0}
293
};
294
 
295
/* Characters that are used to denote comments and line separators. */
296
const char comment_chars[] = "";
297
const char line_comment_chars[] = "#";
298
const char line_separator_chars[] = ";";
299
 
300
/* Characters that can be used to separate the mantissa from the
301
   exponent in floating point numbers. */
302
const char EXP_CHARS[] = "eE";
303
 
304
/* Characters that mean this number is a floating point constant.
305
   As in 0f12.456 or  0d1.2345e12.  */
306
const char FLT_CHARS[] = "fFdDxX";
307
 
308
/* Define bfin-specific command-line options (there are none). */
309
const char *md_shortopts = "";
310
 
311
#define OPTION_FDPIC            (OPTION_MD_BASE)
312
#define OPTION_NOPIC            (OPTION_MD_BASE + 1)
313
 
314
struct option md_longopts[] =
315
{
316
  { "mfdpic",           no_argument,            NULL, OPTION_FDPIC      },
317
  { "mnopic",           no_argument,            NULL, OPTION_NOPIC      },
318
  { "mno-fdpic",        no_argument,            NULL, OPTION_NOPIC      },
319
  { NULL,               no_argument,            NULL, 0                 },
320
};
321
 
322
size_t md_longopts_size = sizeof (md_longopts);
323
 
324
 
325
int
326
md_parse_option (int c ATTRIBUTE_UNUSED, char *arg ATTRIBUTE_UNUSED)
327
{
328
  switch (c)
329
    {
330
    default:
331
      return 0;
332
 
333
    case OPTION_FDPIC:
334
      bfin_flags |= EF_BFIN_FDPIC;
335
      bfin_pic_flag = "-mfdpic";
336
      break;
337
 
338
    case OPTION_NOPIC:
339
      bfin_flags &= ~(EF_BFIN_FDPIC);
340
      bfin_pic_flag = 0;
341
      break;
342
    }
343
 
344
  return 1;
345
}
346
 
347
void
348
md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
349
{
350
  fprintf (stream, _(" BFIN specific command line options:\n"));
351
}
352
 
353
/* Perform machine-specific initializations.  */
354
void
355
md_begin ()
356
{
357
  /* Set the ELF flags if desired. */
358
  if (bfin_flags)
359
    bfd_set_private_flags (stdoutput, bfin_flags);
360
 
361
  /* Set the default machine type. */
362
  if (!bfd_set_arch_mach (stdoutput, bfd_arch_bfin, 0))
363
    as_warn (_("Could not set architecture and machine."));
364
 
365
  /* Ensure that lines can begin with '(', for multiple
366
     register stack pops. */
367
  lex_type ['('] = LEX_BEGIN_NAME;
368
 
369
#ifdef OBJ_ELF
370
  record_alignment (text_section, 2);
371
  record_alignment (data_section, 2);
372
  record_alignment (bss_section, 2);
373
#endif
374
 
375
  errorf = stderr;
376
  obstack_init (&mempool);
377
 
378
#ifdef DEBUG
379
  extern int debug_codeselection;
380
  debug_codeselection = 1;
381
#endif 
382
 
383
  last_insn_size = 0;
384
}
385
 
386
/* Perform the main parsing, and assembly of the input here.  Also,
387
   call the required routines for alignment and fixups here.
388
   This is called for every line that contains real assembly code.  */
389
 
390
void
391
md_assemble (char *line)
392
{
393
  char *toP = 0;
394
  extern char *current_inputline;
395
  int size, insn_size;
396
  struct bfin_insn *tmp_insn;
397
  size_t len;
398
  static size_t buffer_len = 0;
399
  parse_state state;
400
 
401
  len = strlen (line);
402
  if (len + 2 > buffer_len)
403
    {
404
      if (buffer_len > 0)
405
        free (current_inputline);
406
      buffer_len = len + 40;
407
      current_inputline = xmalloc (buffer_len);
408
    }
409
  memcpy (current_inputline, line, len);
410
  current_inputline[len] = ';';
411
  current_inputline[len + 1] = '\0';
412
 
413
  state = parse (current_inputline);
414
  if (state == NO_INSN_GENERATED)
415
    return;
416
 
417
  for (insn_size = 0, tmp_insn = insn; tmp_insn; tmp_insn = tmp_insn->next)
418
    if (!tmp_insn->reloc || !tmp_insn->exp->symbol)
419
      insn_size += 2;
420
 
421
  if (insn_size)
422
    toP = frag_more (insn_size);
423
 
424
  last_insn_size = insn_size;
425
 
426
#ifdef DEBUG
427
  printf ("INS:");
428
#endif
429
  while (insn)
430
    {
431
      if (insn->reloc && insn->exp->symbol)
432
        {
433
          char *prev_toP = toP - 2;
434
          switch (insn->reloc)
435
            {
436
            case BFD_RELOC_BFIN_24_PCREL_JUMP_L:
437
            case BFD_RELOC_24_PCREL:
438
            case BFD_RELOC_BFIN_16_LOW:
439
            case BFD_RELOC_BFIN_16_HIGH:
440
              size = 4;
441
              break;
442
            default:
443
              size = 2;
444
            }
445
 
446
          /* Following if condition checks for the arithmetic relocations.
447
             If the case then it doesn't required to generate the code.
448
             It has been assumed that, their ID will be contiguous.  */
449
          if ((BFD_ARELOC_BFIN_PUSH <= insn->reloc
450
               && BFD_ARELOC_BFIN_COMP >= insn->reloc)
451
              || insn->reloc == BFD_RELOC_BFIN_16_IMM)
452
            {
453
              size = 2;
454
            }
455
          if (insn->reloc == BFD_ARELOC_BFIN_CONST
456
              || insn->reloc == BFD_ARELOC_BFIN_PUSH)
457
            size = 4;
458
 
459
          fix_new (frag_now,
460
                   (prev_toP - frag_now->fr_literal),
461
                   size, insn->exp->symbol, insn->exp->value,
462
                   insn->pcrel, insn->reloc);
463
        }
464
      else
465
        {
466
          md_number_to_chars (toP, insn->value, 2);
467
          toP += 2;
468
        }
469
 
470
#ifdef DEBUG
471
      printf (" reloc :");
472
      printf (" %02x%02x", ((unsigned char *) &insn->value)[0],
473
              ((unsigned char *) &insn->value)[1]);
474
      printf ("\n");
475
#endif
476
      insn = insn->next;
477
    }
478
#ifdef OBJ_ELF
479
  dwarf2_emit_insn (insn_size);
480
#endif
481
}
482
 
483
/* Parse one line of instructions, and generate opcode for it.
484
   To parse the line, YACC and LEX are used, because the instruction set
485
   syntax doesn't confirm to the AT&T assembly syntax.
486
   To call a YACC & LEX generated parser, we must provide the input via
487
   a FILE stream, otherwise stdin is used by default.  Below the input
488
   to the function will be put into a temporary file, then the generated
489
   parser uses the temporary file for parsing.  */
490
 
491
static parse_state
492
parse (char *line)
493
{
494
  parse_state state;
495
  YY_BUFFER_STATE buffstate;
496
 
497
  buffstate = yy_scan_string (line);
498
 
499
  /* our lex requires setting the start state to keyword
500
     every line as the first word may be a keyword.
501
     Fixes a bug where we could not have keywords as labels.  */
502
  set_start_state ();
503
 
504
  /* Call yyparse here.  */
505
  state = yyparse ();
506
  if (state == SEMANTIC_ERROR)
507
    {
508
      as_bad (_("Parse failed."));
509
      insn = 0;
510
    }
511
 
512
  yy_delete_buffer (buffstate);
513
  return state;
514
}
515
 
516
/* We need to handle various expressions properly.
517
   Such as, [SP--] = 34, concerned by md_assemble().  */
518
 
519
void
520
md_operand (expressionS * expressionP)
521
{
522
  if (*input_line_pointer == '[')
523
    {
524
      as_tsktsk ("We found a '['!");
525
      input_line_pointer++;
526
      expression (expressionP);
527
    }
528
}
529
 
530
/* Handle undefined symbols. */
531
symbolS *
532
md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
533
{
534
  return (symbolS *) 0;
535
}
536
 
537
int
538
md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
539
                               segT segment ATTRIBUTE_UNUSED)
540
{
541
  return 0;
542
}
543
 
544
/* Convert from target byte order to host byte order.  */
545
 
546
static int
547
md_chars_to_number (char *val, int n)
548
{
549
  int retval;
550
 
551
  for (retval = 0; n--;)
552
    {
553
      retval <<= 8;
554
      retval |= val[n];
555
    }
556
  return retval;
557
}
558
 
559
void
560
md_apply_fix (fixS *fixP, valueT *valueP, segT seg ATTRIBUTE_UNUSED)
561
{
562
  char *where = fixP->fx_frag->fr_literal + fixP->fx_where;
563
 
564
  long value = *valueP;
565
  long newval;
566
 
567
  switch (fixP->fx_r_type)
568
    {
569
    case BFD_RELOC_BFIN_GOT:
570
    case BFD_RELOC_BFIN_GOT17M4:
571
    case BFD_RELOC_BFIN_FUNCDESC_GOT17M4:
572
      fixP->fx_no_overflow = 1;
573
      newval = md_chars_to_number (where, 2);
574
      newval |= 0x0 & 0x7f;
575
      md_number_to_chars (where, newval, 2);
576
      break;
577
 
578
    case BFD_RELOC_BFIN_10_PCREL:
579
      if (!value)
580
        break;
581
      if (value < -1024 || value > 1022)
582
        as_bad_where (fixP->fx_file, fixP->fx_line,
583
                      _("pcrel too far BFD_RELOC_BFIN_10"));
584
 
585
      /* 11 bit offset even numbered, so we remove right bit.  */
586
      value = value >> 1;
587
      newval = md_chars_to_number (where, 2);
588
      newval |= value & 0x03ff;
589
      md_number_to_chars (where, newval, 2);
590
      break;
591
 
592
    case BFD_RELOC_BFIN_12_PCREL_JUMP:
593
    case BFD_RELOC_BFIN_12_PCREL_JUMP_S:
594
    case BFD_RELOC_12_PCREL:
595
      if (!value)
596
        break;
597
 
598
      if (value < -4096 || value > 4094)
599
        as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far BFD_RELOC_BFIN_12"));
600
      /* 13 bit offset even numbered, so we remove right bit.  */
601
      value = value >> 1;
602
      newval = md_chars_to_number (where, 2);
603
      newval |= value & 0xfff;
604
      md_number_to_chars (where, newval, 2);
605
      break;
606
 
607
    case BFD_RELOC_BFIN_16_LOW:
608
    case BFD_RELOC_BFIN_16_HIGH:
609
      fixP->fx_done = FALSE;
610
      break;
611
 
612
    case BFD_RELOC_BFIN_24_PCREL_JUMP_L:
613
    case BFD_RELOC_BFIN_24_PCREL_CALL_X:
614
    case BFD_RELOC_24_PCREL:
615
      if (!value)
616
        break;
617
 
618
      if (value < -16777216 || value > 16777214)
619
        as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far BFD_RELOC_BFIN_24"));
620
 
621
      /* 25 bit offset even numbered, so we remove right bit.  */
622
      value = value >> 1;
623
      value++;
624
 
625
      md_number_to_chars (where - 2, value >> 16, 1);
626
      md_number_to_chars (where, value, 1);
627
      md_number_to_chars (where + 1, value >> 8, 1);
628
      break;
629
 
630
    case BFD_RELOC_BFIN_5_PCREL:        /* LSETUP (a, b) : "a" */
631
      if (!value)
632
        break;
633
      if (value < 4 || value > 30)
634
        as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far BFD_RELOC_BFIN_5"));
635
      value = value >> 1;
636
      newval = md_chars_to_number (where, 1);
637
      newval = (newval & 0xf0) | (value & 0xf);
638
      md_number_to_chars (where, newval, 1);
639
      break;
640
 
641
    case BFD_RELOC_BFIN_11_PCREL:       /* LSETUP (a, b) : "b" */
642
      if (!value)
643
        break;
644
      value += 2;
645
      if (value < 4 || value > 2046)
646
        as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far BFD_RELOC_BFIN_11_PCREL"));
647
      /* 11 bit unsigned even, so we remove right bit.  */
648
      value = value >> 1;
649
      newval = md_chars_to_number (where, 2);
650
      newval |= value & 0x03ff;
651
      md_number_to_chars (where, newval, 2);
652
      break;
653
 
654
    case BFD_RELOC_8:
655
      if (value < -0x80 || value >= 0x7f)
656
        as_bad_where (fixP->fx_file, fixP->fx_line, _("rel too far BFD_RELOC_8"));
657
      md_number_to_chars (where, value, 1);
658
      break;
659
 
660
    case BFD_RELOC_BFIN_16_IMM:
661
    case BFD_RELOC_16:
662
      if (value < -0x8000 || value >= 0x7fff)
663
        as_bad_where (fixP->fx_file, fixP->fx_line, _("rel too far BFD_RELOC_16"));
664
      md_number_to_chars (where, value, 2);
665
      break;
666
 
667
    case BFD_RELOC_32:
668
      md_number_to_chars (where, value, 4);
669
      break;
670
 
671
    case BFD_RELOC_BFIN_PLTPC:
672
      md_number_to_chars (where, value, 2);
673
      break;
674
 
675
    case BFD_RELOC_BFIN_FUNCDESC:
676
    case BFD_RELOC_VTABLE_INHERIT:
677
    case BFD_RELOC_VTABLE_ENTRY:
678
      fixP->fx_done = FALSE;
679
      break;
680
 
681
    default:
682
      if ((BFD_ARELOC_BFIN_PUSH > fixP->fx_r_type) || (BFD_ARELOC_BFIN_COMP < fixP->fx_r_type))
683
        {
684
          fprintf (stderr, "Relocation %d not handled in gas." " Contact support.\n", fixP->fx_r_type);
685
          return;
686
        }
687
    }
688
 
689
  if (!fixP->fx_addsy)
690
    fixP->fx_done = TRUE;
691
 
692
}
693
 
694
/* Round up a section size to the appropriate boundary.  */
695
valueT
696
md_section_align (segment, size)
697
     segT segment;
698
     valueT size;
699
{
700
  int boundary = bfd_get_section_alignment (stdoutput, segment);
701
  return ((size + (1 << boundary) - 1) & (-1 << boundary));
702
}
703
 
704
 
705
char *
706
md_atof (int type, char * litP, int * sizeP)
707
{
708
  return ieee_md_atof (type, litP, sizeP, FALSE);
709
}
710
 
711
 
712
/* If while processing a fixup, a reloc really needs to be created
713
   then it is done here.  */
714
 
715
arelent *
716
tc_gen_reloc (seg, fixp)
717
     asection *seg ATTRIBUTE_UNUSED;
718
     fixS *fixp;
719
{
720
  arelent *reloc;
721
 
722
  reloc               = (arelent *) xmalloc (sizeof (arelent));
723
  reloc->sym_ptr_ptr  = (asymbol **) xmalloc (sizeof (asymbol *));
724
  *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
725
  reloc->address      = fixp->fx_frag->fr_address + fixp->fx_where;
726
 
727
  reloc->addend = fixp->fx_offset;
728
  reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
729
 
730
  if (reloc->howto == (reloc_howto_type *) NULL)
731
    {
732
      as_bad_where (fixp->fx_file, fixp->fx_line,
733
                    /* xgettext:c-format.  */
734
                    _("reloc %d not supported by object file format"),
735
                    (int) fixp->fx_r_type);
736
 
737
      xfree (reloc);
738
 
739
      return NULL;
740
    }
741
 
742
  return reloc;
743
}
744
 
745
/*  The location from which a PC relative jump should be calculated,
746
    given a PC relative reloc.  */
747
 
748
long
749
md_pcrel_from_section (fixP, sec)
750
     fixS *fixP;
751
     segT sec;
752
{
753
  if (fixP->fx_addsy != (symbolS *) NULL
754
      && (!S_IS_DEFINED (fixP->fx_addsy)
755
      || S_GET_SEGMENT (fixP->fx_addsy) != sec))
756
    {
757
      /* The symbol is undefined (or is defined but not in this section).
758
         Let the linker figure it out.  */
759
      return 0;
760
    }
761
  return fixP->fx_frag->fr_address + fixP->fx_where;
762
}
763
 
764
/* Return true if the fix can be handled by GAS, false if it must
765
   be passed through to the linker.  */
766
 
767
bfd_boolean
768
bfin_fix_adjustable (fixS *fixP)
769
{
770
  switch (fixP->fx_r_type)
771
    {
772
  /* Adjust_reloc_syms doesn't know about the GOT.  */
773
    case BFD_RELOC_BFIN_GOT:
774
    case BFD_RELOC_BFIN_GOT17M4:
775
    case BFD_RELOC_BFIN_FUNCDESC_GOT17M4:
776
    case BFD_RELOC_BFIN_PLTPC:
777
  /* We need the symbol name for the VTABLE entries.  */
778
    case BFD_RELOC_VTABLE_INHERIT:
779
    case BFD_RELOC_VTABLE_ENTRY:
780
      return 0;
781
 
782
    default:
783
      return 1;
784
    }
785
}
786
 
787
 
788
/* Handle the LOOP_BEGIN and LOOP_END statements.
789
   Parse the Loop_Begin/Loop_End and create a label.  */
790
void
791
bfin_start_line_hook ()
792
{
793
  bfd_boolean maybe_begin = FALSE;
794
  bfd_boolean maybe_end = FALSE;
795
 
796
  char *c1, *label_name;
797
  symbolS *line_label;
798
  char *c = input_line_pointer;
799
  int cr_num = 0;
800
 
801
  while (ISSPACE (*c))
802
    {
803
      if (*c == '\n')
804
        cr_num++;
805
      c++;
806
    }
807
 
808
  /* Look for Loop_Begin or Loop_End statements.  */
809
 
810
  if (*c != 'L' && *c != 'l')
811
    return;
812
 
813
  c++;
814
  if (*c != 'O' && *c != 'o')
815
    return;
816
 
817
  c++;
818
  if (*c != 'O' && *c != 'o')
819
    return;
820
 
821
  c++;
822
  if (*c != 'P' && *c != 'p')
823
    return;
824
 
825
  c++;
826
  if (*c != '_')
827
    return;
828
 
829
  c++;
830
  if (*c == 'E' || *c == 'e')
831
    maybe_end = TRUE;
832
  else if (*c == 'B' || *c == 'b')
833
    maybe_begin = TRUE;
834
  else
835
    return;
836
 
837
  if (maybe_end)
838
    {
839
      c++;
840
      if (*c != 'N' && *c != 'n')
841
        return;
842
 
843
      c++;
844
      if (*c != 'D' && *c != 'd')
845
        return;
846
    }
847
 
848
  if (maybe_begin)
849
    {
850
      c++;
851
      if (*c != 'E' && *c != 'e')
852
        return;
853
 
854
      c++;
855
      if (*c != 'G' && *c != 'g')
856
        return;
857
 
858
      c++;
859
      if (*c != 'I' && *c != 'i')
860
        return;
861
 
862
      c++;
863
      if (*c != 'N' && *c != 'n')
864
        return;
865
    }
866
 
867
  c++;
868
  while (ISSPACE (*c)) c++;
869
  c1 = c;
870
  while (ISALPHA (*c) || ISDIGIT (*c) || *c == '_') c++;
871
 
872
  if (input_line_pointer[-1] == '\n')
873
    bump_line_counters ();
874
 
875
  while (cr_num--)
876
    bump_line_counters ();
877
 
878
  input_line_pointer = c;
879
  if (maybe_end)
880
    {
881
      label_name = (char *) xmalloc ((c - c1) + strlen ("__END") + 5);
882
      label_name[0] = 0;
883
      strcat (label_name, "L$L$");
884
      strncat (label_name, c1, c-c1);
885
      strcat (label_name, "__END");
886
    }
887
  else /* maybe_begin.  */
888
    {
889
      label_name = (char *) xmalloc ((c - c1) + strlen ("__BEGIN") + 5);
890
      label_name[0] = 0;
891
      strcat (label_name, "L$L$");
892
      strncat (label_name, c1, c-c1);
893
      strcat (label_name, "__BEGIN");
894
    }
895
 
896
  line_label = colon (label_name);
897
 
898
  /* Loop_End follows the last instruction in the loop.
899
     Adjust label address.  */
900
  if (maybe_end)
901
    ((struct local_symbol *) line_label)->lsy_value -= last_insn_size;
902
}
903
 
904
/* Special extra functions that help bfin-parse.y perform its job.  */
905
 
906
#include <assert.h>
907
 
908
struct obstack mempool;
909
 
910
INSTR_T
911
conscode (INSTR_T head, INSTR_T tail)
912
{
913
  if (!head)
914
    return tail;
915
  head->next = tail;
916
  return head;
917
}
918
 
919
INSTR_T
920
conctcode (INSTR_T head, INSTR_T tail)
921
{
922
  INSTR_T temp = (head);
923
  if (!head)
924
    return tail;
925
  while (temp->next)
926
    temp = temp->next;
927
  temp->next = tail;
928
 
929
  return head;
930
}
931
 
932
INSTR_T
933
note_reloc (INSTR_T code, Expr_Node * symbol, int reloc, int pcrel)
934
{
935
  /* Assert that the symbol is not an operator.  */
936
  assert (symbol->type == Expr_Node_Reloc);
937
 
938
  return note_reloc1 (code, symbol->value.s_value, reloc, pcrel);
939
 
940
}
941
 
942
INSTR_T
943
note_reloc1 (INSTR_T code, const char *symbol, int reloc, int pcrel)
944
{
945
  code->reloc = reloc;
946
  code->exp = mkexpr (0, symbol_find_or_make (symbol));
947
  code->pcrel = pcrel;
948
  return code;
949
}
950
 
951
INSTR_T
952
note_reloc2 (INSTR_T code, const char *symbol, int reloc, int value, int pcrel)
953
{
954
  code->reloc = reloc;
955
  code->exp = mkexpr (value, symbol_find_or_make (symbol));
956
  code->pcrel = pcrel;
957
  return code;
958
}
959
 
960
INSTR_T
961
gencode (unsigned long x)
962
{
963
  INSTR_T cell = (INSTR_T) obstack_alloc (&mempool, sizeof (struct bfin_insn));
964
  memset (cell, 0, sizeof (struct bfin_insn));
965
  cell->value = (x);
966
  return cell;
967
}
968
 
969
int reloc;
970
int ninsns;
971
int count_insns;
972
 
973
static void *
974
allocate (int n)
975
{
976
  return (void *) obstack_alloc (&mempool, n);
977
}
978
 
979
Expr_Node *
980
Expr_Node_Create (Expr_Node_Type type,
981
                  Expr_Node_Value value,
982
                  Expr_Node *Left_Child,
983
                  Expr_Node *Right_Child)
984
{
985
 
986
 
987
  Expr_Node *node = (Expr_Node *) allocate (sizeof (Expr_Node));
988
  node->type = type;
989
  node->value = value;
990
  node->Left_Child = Left_Child;
991
  node->Right_Child = Right_Child;
992
  return node;
993
}
994
 
995
static const char *con = ".__constant";
996
static const char *op = ".__operator";
997
static INSTR_T Expr_Node_Gen_Reloc_R (Expr_Node * head);
998
INSTR_T Expr_Node_Gen_Reloc (Expr_Node *head, int parent_reloc);
999
 
1000
INSTR_T
1001
Expr_Node_Gen_Reloc (Expr_Node * head, int parent_reloc)
1002
{
1003
  /* Top level reloction expression generator VDSP style.
1004
   If the relocation is just by itself, generate one item
1005
   else generate this convoluted expression.  */
1006
 
1007
  INSTR_T note = NULL_CODE;
1008
  INSTR_T note1 = NULL_CODE;
1009
  int pcrel = 1;  /* Is the parent reloc pcrelative?
1010
                  This calculation here and HOWTO should match.  */
1011
 
1012
  if (parent_reloc)
1013
    {
1014
      /*  If it's 32 bit quantity then 16bit code needs to be added.  */
1015
      int value = 0;
1016
 
1017
      if (head->type == Expr_Node_Constant)
1018
        {
1019
          /* If note1 is not null code, we have to generate a right
1020
             aligned value for the constant. Otherwise the reloc is
1021
             a part of the basic command and the yacc file
1022
             generates this.  */
1023
          value = head->value.i_value;
1024
        }
1025
      switch (parent_reloc)
1026
        {
1027
          /*  Some relocations will need to allocate extra words.  */
1028
        case BFD_RELOC_BFIN_16_IMM:
1029
        case BFD_RELOC_BFIN_16_LOW:
1030
        case BFD_RELOC_BFIN_16_HIGH:
1031
          note1 = conscode (gencode (value), NULL_CODE);
1032
          pcrel = 0;
1033
          break;
1034
        case BFD_RELOC_BFIN_PLTPC:
1035
          note1 = conscode (gencode (value), NULL_CODE);
1036
          pcrel = 0;
1037
          break;
1038
        case BFD_RELOC_16:
1039
        case BFD_RELOC_BFIN_GOT:
1040
        case BFD_RELOC_BFIN_GOT17M4:
1041
        case BFD_RELOC_BFIN_FUNCDESC_GOT17M4:
1042
          note1 = conscode (gencode (value), NULL_CODE);
1043
          pcrel = 0;
1044
          break;
1045
        case BFD_RELOC_24_PCREL:
1046
        case BFD_RELOC_BFIN_24_PCREL_JUMP_L:
1047
        case BFD_RELOC_BFIN_24_PCREL_CALL_X:
1048
          /* These offsets are even numbered pcrel.  */
1049
          note1 = conscode (gencode (value >> 1), NULL_CODE);
1050
          break;
1051
        default:
1052
          note1 = NULL_CODE;
1053
        }
1054
    }
1055
  if (head->type == Expr_Node_Constant)
1056
    note = note1;
1057
  else if (head->type == Expr_Node_Reloc)
1058
    {
1059
      note = note_reloc1 (gencode (0), head->value.s_value, parent_reloc, pcrel);
1060
      if (note1 != NULL_CODE)
1061
        note = conscode (note1, note);
1062
    }
1063
  else if (head->type == Expr_Node_Binop
1064
           && (head->value.op_value == Expr_Op_Type_Add
1065
               || head->value.op_value == Expr_Op_Type_Sub)
1066
           && head->Left_Child->type == Expr_Node_Reloc
1067
           && head->Right_Child->type == Expr_Node_Constant)
1068
    {
1069
      int val = head->Right_Child->value.i_value;
1070
      if (head->value.op_value == Expr_Op_Type_Sub)
1071
        val = -val;
1072
      note = conscode (note_reloc2 (gencode (0), head->Left_Child->value.s_value,
1073
                                    parent_reloc, val, 0),
1074
                       NULL_CODE);
1075
      if (note1 != NULL_CODE)
1076
        note = conscode (note1, note);
1077
    }
1078
  else
1079
    {
1080
      /* Call the recursive function.  */
1081
      note = note_reloc1 (gencode (0), op, parent_reloc, pcrel);
1082
      if (note1 != NULL_CODE)
1083
        note = conscode (note1, note);
1084
      note = conctcode (Expr_Node_Gen_Reloc_R (head), note);
1085
    }
1086
  return note;
1087
}
1088
 
1089
static INSTR_T
1090
Expr_Node_Gen_Reloc_R (Expr_Node * head)
1091
{
1092
 
1093
  INSTR_T note = 0;
1094
  INSTR_T note1 = 0;
1095
 
1096
  switch (head->type)
1097
    {
1098
    case Expr_Node_Constant:
1099
      note = conscode (note_reloc2 (gencode (0), con, BFD_ARELOC_BFIN_CONST, head->value.i_value, 0), NULL_CODE);
1100
      break;
1101
    case Expr_Node_Reloc:
1102
      note = conscode (note_reloc (gencode (0), head, BFD_ARELOC_BFIN_PUSH, 0), NULL_CODE);
1103
      break;
1104
    case Expr_Node_Binop:
1105
      note1 = conctcode (Expr_Node_Gen_Reloc_R (head->Left_Child), Expr_Node_Gen_Reloc_R (head->Right_Child));
1106
      switch (head->value.op_value)
1107
        {
1108
        case Expr_Op_Type_Add:
1109
          note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_ADD, 0), NULL_CODE));
1110
          break;
1111
        case Expr_Op_Type_Sub:
1112
          note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_SUB, 0), NULL_CODE));
1113
          break;
1114
        case Expr_Op_Type_Mult:
1115
          note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_MULT, 0), NULL_CODE));
1116
          break;
1117
        case Expr_Op_Type_Div:
1118
          note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_DIV, 0), NULL_CODE));
1119
          break;
1120
        case Expr_Op_Type_Mod:
1121
          note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_MOD, 0), NULL_CODE));
1122
          break;
1123
        case Expr_Op_Type_Lshift:
1124
          note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LSHIFT, 0), NULL_CODE));
1125
          break;
1126
        case Expr_Op_Type_Rshift:
1127
          note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_RSHIFT, 0), NULL_CODE));
1128
          break;
1129
        case Expr_Op_Type_BAND:
1130
          note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_AND, 0), NULL_CODE));
1131
          break;
1132
        case Expr_Op_Type_BOR:
1133
          note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_OR, 0), NULL_CODE));
1134
          break;
1135
        case Expr_Op_Type_BXOR:
1136
          note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_XOR, 0), NULL_CODE));
1137
          break;
1138
        case Expr_Op_Type_LAND:
1139
          note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LAND, 0), NULL_CODE));
1140
          break;
1141
        case Expr_Op_Type_LOR:
1142
          note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LOR, 0), NULL_CODE));
1143
          break;
1144
        default:
1145
          fprintf (stderr, "%s:%d:Unknown operator found for arithmetic" " relocation", __FILE__, __LINE__);
1146
 
1147
 
1148
        }
1149
      break;
1150
    case Expr_Node_Unop:
1151
      note1 = conscode (Expr_Node_Gen_Reloc_R (head->Left_Child), NULL_CODE);
1152
      switch (head->value.op_value)
1153
        {
1154
        case Expr_Op_Type_NEG:
1155
          note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_NEG, 0), NULL_CODE));
1156
          break;
1157
        case Expr_Op_Type_COMP:
1158
          note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_COMP, 0), NULL_CODE));
1159
          break;
1160
        default:
1161
          fprintf (stderr, "%s:%d:Unknown operator found for arithmetic" " relocation", __FILE__, __LINE__);
1162
        }
1163
      break;
1164
    default:
1165
      fprintf (stderr, "%s:%d:Unknown node expression found during " "arithmetic relocation generation", __FILE__, __LINE__);
1166
    }
1167
  return note;
1168
}
1169
 
1170
 
1171
/* Blackfin opcode generation.  */
1172
 
1173
/* These functions are called by the generated parser
1174
   (from bfin-parse.y), the register type classification
1175
   happens in bfin-lex.l.  */
1176
 
1177
#include "bfin-aux.h"
1178
#include "opcode/bfin.h"
1179
 
1180
#define INIT(t)  t c_code = init_##t
1181
#define ASSIGN(x) c_code.opcode |= ((x & c_code.mask_##x)<<c_code.bits_##x)
1182
#define ASSIGN_R(x) c_code.opcode |= (((x ? (x->regno & CODE_MASK) : 0) & c_code.mask_##x)<<c_code.bits_##x)
1183
 
1184
#define HI(x) ((x >> 16) & 0xffff)
1185
#define LO(x) ((x      ) & 0xffff)
1186
 
1187
#define GROUP(x) ((x->regno & CLASS_MASK) >> 4)
1188
 
1189
#define GEN_OPCODE32()  \
1190
        conscode (gencode (HI (c_code.opcode)), \
1191
        conscode (gencode (LO (c_code.opcode)), NULL_CODE))
1192
 
1193
#define GEN_OPCODE16()  \
1194
        conscode (gencode (c_code.opcode), NULL_CODE)
1195
 
1196
 
1197
/*  32 BIT INSTRUCTIONS.  */
1198
 
1199
 
1200
/* DSP32 instruction generation.  */
1201
 
1202
INSTR_T
1203
bfin_gen_dsp32mac (int op1, int MM, int mmod, int w1, int P,
1204
                   int h01, int h11, int h00, int h10, int op0,
1205
                   REG_T dst, REG_T src0, REG_T src1, int w0)
1206
{
1207
  INIT (DSP32Mac);
1208
 
1209
  ASSIGN (op0);
1210
  ASSIGN (op1);
1211
  ASSIGN (MM);
1212
  ASSIGN (mmod);
1213
  ASSIGN (w0);
1214
  ASSIGN (w1);
1215
  ASSIGN (h01);
1216
  ASSIGN (h11);
1217
  ASSIGN (h00);
1218
  ASSIGN (h10);
1219
  ASSIGN (P);
1220
 
1221
  /* If we have full reg assignments, mask out LSB to encode
1222
  single or simultaneous even/odd register moves.  */
1223
  if (P)
1224
    {
1225
      dst->regno &= 0x06;
1226
    }
1227
 
1228
  ASSIGN_R (dst);
1229
  ASSIGN_R (src0);
1230
  ASSIGN_R (src1);
1231
 
1232
  return GEN_OPCODE32 ();
1233
}
1234
 
1235
INSTR_T
1236
bfin_gen_dsp32mult (int op1, int MM, int mmod, int w1, int P,
1237
                    int h01, int h11, int h00, int h10, int op0,
1238
                    REG_T dst, REG_T src0, REG_T src1, int w0)
1239
{
1240
  INIT (DSP32Mult);
1241
 
1242
  ASSIGN (op0);
1243
  ASSIGN (op1);
1244
  ASSIGN (MM);
1245
  ASSIGN (mmod);
1246
  ASSIGN (w0);
1247
  ASSIGN (w1);
1248
  ASSIGN (h01);
1249
  ASSIGN (h11);
1250
  ASSIGN (h00);
1251
  ASSIGN (h10);
1252
  ASSIGN (P);
1253
 
1254
  if (P)
1255
    {
1256
      dst->regno &= 0x06;
1257
    }
1258
 
1259
  ASSIGN_R (dst);
1260
  ASSIGN_R (src0);
1261
  ASSIGN_R (src1);
1262
 
1263
  return GEN_OPCODE32 ();
1264
}
1265
 
1266
INSTR_T
1267
bfin_gen_dsp32alu (int HL, int aopcde, int aop, int s, int x,
1268
              REG_T dst0, REG_T dst1, REG_T src0, REG_T src1)
1269
{
1270
  INIT (DSP32Alu);
1271
 
1272
  ASSIGN (HL);
1273
  ASSIGN (aopcde);
1274
  ASSIGN (aop);
1275
  ASSIGN (s);
1276
  ASSIGN (x);
1277
  ASSIGN_R (dst0);
1278
  ASSIGN_R (dst1);
1279
  ASSIGN_R (src0);
1280
  ASSIGN_R (src1);
1281
 
1282
  return GEN_OPCODE32 ();
1283
}
1284
 
1285
INSTR_T
1286
bfin_gen_dsp32shift (int sopcde, REG_T dst0, REG_T src0,
1287
                REG_T src1, int sop, int HLs)
1288
{
1289
  INIT (DSP32Shift);
1290
 
1291
  ASSIGN (sopcde);
1292
  ASSIGN (sop);
1293
  ASSIGN (HLs);
1294
 
1295
  ASSIGN_R (dst0);
1296
  ASSIGN_R (src0);
1297
  ASSIGN_R (src1);
1298
 
1299
  return GEN_OPCODE32 ();
1300
}
1301
 
1302
INSTR_T
1303
bfin_gen_dsp32shiftimm (int sopcde, REG_T dst0, int immag,
1304
                   REG_T src1, int sop, int HLs)
1305
{
1306
  INIT (DSP32ShiftImm);
1307
 
1308
  ASSIGN (sopcde);
1309
  ASSIGN (sop);
1310
  ASSIGN (HLs);
1311
 
1312
  ASSIGN_R (dst0);
1313
  ASSIGN (immag);
1314
  ASSIGN_R (src1);
1315
 
1316
  return GEN_OPCODE32 ();
1317
}
1318
 
1319
/* LOOP SETUP.  */
1320
 
1321
INSTR_T
1322
bfin_gen_loopsetup (Expr_Node * psoffset, REG_T c, int rop,
1323
               Expr_Node * peoffset, REG_T reg)
1324
{
1325
  int soffset, eoffset;
1326
  INIT (LoopSetup);
1327
 
1328
  soffset = (EXPR_VALUE (psoffset) >> 1);
1329
  ASSIGN (soffset);
1330
  eoffset = (EXPR_VALUE (peoffset) >> 1);
1331
  ASSIGN (eoffset);
1332
  ASSIGN (rop);
1333
  ASSIGN_R (c);
1334
  ASSIGN_R (reg);
1335
 
1336
  return
1337
      conscode (gencode (HI (c_code.opcode)),
1338
                conctcode (Expr_Node_Gen_Reloc (psoffset, BFD_RELOC_BFIN_5_PCREL),
1339
                           conctcode (gencode (LO (c_code.opcode)), Expr_Node_Gen_Reloc (peoffset, BFD_RELOC_BFIN_11_PCREL))));
1340
 
1341
}
1342
 
1343
/*  Call, Link.  */
1344
 
1345
INSTR_T
1346
bfin_gen_calla (Expr_Node * addr, int S)
1347
{
1348
  int val;
1349
  int high_val;
1350
  int reloc = 0;
1351
  INIT (CALLa);
1352
 
1353
  switch(S){
1354
   case 0 : reloc = BFD_RELOC_BFIN_24_PCREL_JUMP_L; break;
1355
   case 1 : reloc = BFD_RELOC_24_PCREL; break;
1356
   case 2 : reloc = BFD_RELOC_BFIN_PLTPC; break;
1357
   default : break;
1358
  }
1359
 
1360
  ASSIGN (S);
1361
 
1362
  val = EXPR_VALUE (addr) >> 1;
1363
  high_val = val >> 16;
1364
 
1365
  return conscode (gencode (HI (c_code.opcode) | (high_val & 0xff)),
1366
                     Expr_Node_Gen_Reloc (addr, reloc));
1367
  }
1368
 
1369
INSTR_T
1370
bfin_gen_linkage (int R, int framesize)
1371
{
1372
  INIT (Linkage);
1373
 
1374
  ASSIGN (R);
1375
  ASSIGN (framesize);
1376
 
1377
  return GEN_OPCODE32 ();
1378
}
1379
 
1380
 
1381
/* Load and Store.  */
1382
 
1383
INSTR_T
1384
bfin_gen_ldimmhalf (REG_T reg, int H, int S, int Z, Expr_Node * phword, int reloc)
1385
{
1386
  int grp, hword;
1387
  unsigned val = EXPR_VALUE (phword);
1388
  INIT (LDIMMhalf);
1389
 
1390
  ASSIGN (H);
1391
  ASSIGN (S);
1392
  ASSIGN (Z);
1393
 
1394
  ASSIGN_R (reg);
1395
  grp = (GROUP (reg));
1396
  ASSIGN (grp);
1397
  if (reloc == 2)
1398
    {
1399
      return conscode (gencode (HI (c_code.opcode)), Expr_Node_Gen_Reloc (phword, BFD_RELOC_BFIN_16_IMM));
1400
    }
1401
  else if (reloc == 1)
1402
    {
1403
      return conscode (gencode (HI (c_code.opcode)), Expr_Node_Gen_Reloc (phword, IS_H (*reg) ? BFD_RELOC_BFIN_16_HIGH : BFD_RELOC_BFIN_16_LOW));
1404
    }
1405
  else
1406
    {
1407
      hword = val;
1408
      ASSIGN (hword);
1409
    }
1410
  return GEN_OPCODE32 ();
1411
}
1412
 
1413
INSTR_T
1414
bfin_gen_ldstidxi (REG_T ptr, REG_T reg, int W, int sz, int Z, Expr_Node * poffset)
1415
{
1416
  INIT (LDSTidxI);
1417
 
1418
  if (!IS_PREG (*ptr) || (!IS_DREG (*reg) && !Z))
1419
    {
1420
      fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1421
      return 0;
1422
    }
1423
 
1424
  ASSIGN_R (ptr);
1425
  ASSIGN_R (reg);
1426
  ASSIGN (W);
1427
  ASSIGN (sz);
1428
 
1429
  ASSIGN (Z);
1430
 
1431
  if (poffset->type != Expr_Node_Constant)
1432
    {
1433
      /* a GOT relocation such as R0 = [P5 + symbol@GOT] */
1434
      /* distinguish between R0 = [P5 + symbol@GOT] and
1435
         P5 = [P5 + _current_shared_library_p5_offset_]
1436
      */
1437
      if (poffset->type == Expr_Node_Reloc
1438
          && !strcmp (poffset->value.s_value,
1439
                      "_current_shared_library_p5_offset_"))
1440
        {
1441
          return  conscode (gencode (HI (c_code.opcode)),
1442
                            Expr_Node_Gen_Reloc(poffset, BFD_RELOC_16));
1443
        }
1444
      else if (poffset->type != Expr_Node_GOT_Reloc)
1445
        abort ();
1446
 
1447
      return conscode (gencode (HI (c_code.opcode)),
1448
                       Expr_Node_Gen_Reloc(poffset->Left_Child,
1449
                                           poffset->value.i_value));
1450
    }
1451
  else
1452
    {
1453
      int value, offset;
1454
      switch (sz)
1455
        {                               // load/store access size
1456
        case 0:                  // 32 bit
1457
          value = EXPR_VALUE (poffset) >> 2;
1458
          break;
1459
        case 1:                 // 16 bit
1460
          value = EXPR_VALUE (poffset) >> 1;
1461
          break;
1462
        case 2:                 // 8 bit
1463
          value = EXPR_VALUE (poffset);
1464
          break;
1465
        default:
1466
          abort ();
1467
        }
1468
 
1469
      offset = (value & 0xffff);
1470
      ASSIGN (offset);
1471
      return GEN_OPCODE32 ();
1472
    }
1473
}
1474
 
1475
 
1476
INSTR_T
1477
bfin_gen_ldst (REG_T ptr, REG_T reg, int aop, int sz, int Z, int W)
1478
{
1479
  INIT (LDST);
1480
 
1481
  if (!IS_PREG (*ptr) || (!IS_DREG (*reg) && !Z))
1482
    {
1483
      fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1484
      return 0;
1485
    }
1486
 
1487
  ASSIGN_R (ptr);
1488
  ASSIGN_R (reg);
1489
  ASSIGN (aop);
1490
  ASSIGN (sz);
1491
  ASSIGN (Z);
1492
  ASSIGN (W);
1493
 
1494
  return GEN_OPCODE16 ();
1495
}
1496
 
1497
INSTR_T
1498
bfin_gen_ldstii (REG_T ptr, REG_T reg, Expr_Node * poffset, int W, int op)
1499
{
1500
  int offset;
1501
  int value = 0;
1502
  INIT (LDSTii);
1503
 
1504
 
1505
  if (!IS_PREG (*ptr))
1506
    {
1507
      fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1508
      return 0;
1509
    }
1510
 
1511
  switch (op)
1512
    {
1513
    case 1:
1514
    case 2:
1515
      value = EXPR_VALUE (poffset) >> 1;
1516
      break;
1517
    case 0:
1518
    case 3:
1519
      value = EXPR_VALUE (poffset) >> 2;
1520
      break;
1521
    }
1522
 
1523
  ASSIGN_R (ptr);
1524
  ASSIGN_R (reg);
1525
 
1526
  offset = value;
1527
  ASSIGN (offset);
1528
  ASSIGN (W);
1529
  ASSIGN (op);
1530
 
1531
  return GEN_OPCODE16 ();
1532
}
1533
 
1534
INSTR_T
1535
bfin_gen_ldstiifp (REG_T sreg, Expr_Node * poffset, int W)
1536
{
1537
  /* Set bit 4 if it's a Preg.  */
1538
  int reg = (sreg->regno & CODE_MASK) | (IS_PREG (*sreg) ? 0x8 : 0x0);
1539
  int offset = ((~(EXPR_VALUE (poffset) >> 2)) & 0x1f) + 1;
1540
  INIT (LDSTiiFP);
1541
  ASSIGN (reg);
1542
  ASSIGN (offset);
1543
  ASSIGN (W);
1544
 
1545
  return GEN_OPCODE16 ();
1546
}
1547
 
1548
INSTR_T
1549
bfin_gen_ldstpmod (REG_T ptr, REG_T reg, int aop, int W, REG_T idx)
1550
{
1551
  INIT (LDSTpmod);
1552
 
1553
  ASSIGN_R (ptr);
1554
  ASSIGN_R (reg);
1555
  ASSIGN (aop);
1556
  ASSIGN (W);
1557
  ASSIGN_R (idx);
1558
 
1559
  return GEN_OPCODE16 ();
1560
}
1561
 
1562
INSTR_T
1563
bfin_gen_dspldst (REG_T i, REG_T reg, int aop, int W, int m)
1564
{
1565
  INIT (DspLDST);
1566
 
1567
  ASSIGN_R (i);
1568
  ASSIGN_R (reg);
1569
  ASSIGN (aop);
1570
  ASSIGN (W);
1571
  ASSIGN (m);
1572
 
1573
  return GEN_OPCODE16 ();
1574
}
1575
 
1576
INSTR_T
1577
bfin_gen_logi2op (int opc, int src, int dst)
1578
{
1579
  INIT (LOGI2op);
1580
 
1581
  ASSIGN (opc);
1582
  ASSIGN (src);
1583
  ASSIGN (dst);
1584
 
1585
  return GEN_OPCODE16 ();
1586
}
1587
 
1588
INSTR_T
1589
bfin_gen_brcc (int T, int B, Expr_Node * poffset)
1590
{
1591
  int offset;
1592
  INIT (BRCC);
1593
 
1594
  ASSIGN (T);
1595
  ASSIGN (B);
1596
  offset = ((EXPR_VALUE (poffset) >> 1));
1597
  ASSIGN (offset);
1598
  return conscode (gencode (c_code.opcode), Expr_Node_Gen_Reloc (poffset, BFD_RELOC_BFIN_10_PCREL));
1599
}
1600
 
1601
INSTR_T
1602
bfin_gen_ujump (Expr_Node * poffset)
1603
{
1604
  int offset;
1605
  INIT (UJump);
1606
 
1607
  offset = ((EXPR_VALUE (poffset) >> 1));
1608
  ASSIGN (offset);
1609
 
1610
  return conscode (gencode (c_code.opcode),
1611
                   Expr_Node_Gen_Reloc (
1612
                       poffset, BFD_RELOC_BFIN_12_PCREL_JUMP_S));
1613
}
1614
 
1615
INSTR_T
1616
bfin_gen_alu2op (REG_T dst, REG_T src, int opc)
1617
{
1618
  INIT (ALU2op);
1619
 
1620
  ASSIGN_R (dst);
1621
  ASSIGN_R (src);
1622
  ASSIGN (opc);
1623
 
1624
  return GEN_OPCODE16 ();
1625
}
1626
 
1627
INSTR_T
1628
bfin_gen_compi2opd (REG_T dst, int src, int op)
1629
{
1630
  INIT (COMPI2opD);
1631
 
1632
  ASSIGN_R (dst);
1633
  ASSIGN (src);
1634
  ASSIGN (op);
1635
 
1636
  return GEN_OPCODE16 ();
1637
}
1638
 
1639
INSTR_T
1640
bfin_gen_compi2opp (REG_T dst, int src, int op)
1641
{
1642
  INIT (COMPI2opP);
1643
 
1644
  ASSIGN_R (dst);
1645
  ASSIGN (src);
1646
  ASSIGN (op);
1647
 
1648
  return GEN_OPCODE16 ();
1649
}
1650
 
1651
INSTR_T
1652
bfin_gen_dagmodik (REG_T i, int op)
1653
{
1654
  INIT (DagMODik);
1655
 
1656
  ASSIGN_R (i);
1657
  ASSIGN (op);
1658
 
1659
  return GEN_OPCODE16 ();
1660
}
1661
 
1662
INSTR_T
1663
bfin_gen_dagmodim (REG_T i, REG_T m, int op, int br)
1664
{
1665
  INIT (DagMODim);
1666
 
1667
  ASSIGN_R (i);
1668
  ASSIGN_R (m);
1669
  ASSIGN (op);
1670
  ASSIGN (br);
1671
 
1672
  return GEN_OPCODE16 ();
1673
}
1674
 
1675
INSTR_T
1676
bfin_gen_ptr2op (REG_T dst, REG_T src, int opc)
1677
{
1678
  INIT (PTR2op);
1679
 
1680
  ASSIGN_R (dst);
1681
  ASSIGN_R (src);
1682
  ASSIGN (opc);
1683
 
1684
  return GEN_OPCODE16 ();
1685
}
1686
 
1687
INSTR_T
1688
bfin_gen_comp3op (REG_T src0, REG_T src1, REG_T dst, int opc)
1689
{
1690
  INIT (COMP3op);
1691
 
1692
  ASSIGN_R (src0);
1693
  ASSIGN_R (src1);
1694
  ASSIGN_R (dst);
1695
  ASSIGN (opc);
1696
 
1697
  return GEN_OPCODE16 ();
1698
}
1699
 
1700
INSTR_T
1701
bfin_gen_ccflag (REG_T x, int y, int opc, int I, int G)
1702
{
1703
  INIT (CCflag);
1704
 
1705
  ASSIGN_R (x);
1706
  ASSIGN (y);
1707
  ASSIGN (opc);
1708
  ASSIGN (I);
1709
  ASSIGN (G);
1710
 
1711
  return GEN_OPCODE16 ();
1712
}
1713
 
1714
INSTR_T
1715
bfin_gen_ccmv (REG_T src, REG_T dst, int T)
1716
{
1717
  int s, d;
1718
  INIT (CCmv);
1719
 
1720
  ASSIGN_R (src);
1721
  ASSIGN_R (dst);
1722
  s = (GROUP (src));
1723
  ASSIGN (s);
1724
  d = (GROUP (dst));
1725
  ASSIGN (d);
1726
  ASSIGN (T);
1727
 
1728
  return GEN_OPCODE16 ();
1729
}
1730
 
1731
INSTR_T
1732
bfin_gen_cc2stat (int cbit, int op, int D)
1733
{
1734
  INIT (CC2stat);
1735
 
1736
  ASSIGN (cbit);
1737
  ASSIGN (op);
1738
  ASSIGN (D);
1739
 
1740
  return GEN_OPCODE16 ();
1741
}
1742
 
1743
INSTR_T
1744
bfin_gen_regmv (REG_T src, REG_T dst)
1745
{
1746
  int gs, gd;
1747
  INIT (RegMv);
1748
 
1749
  ASSIGN_R (src);
1750
  ASSIGN_R (dst);
1751
 
1752
  gs = (GROUP (src));
1753
  ASSIGN (gs);
1754
  gd = (GROUP (dst));
1755
  ASSIGN (gd);
1756
 
1757
  return GEN_OPCODE16 ();
1758
}
1759
 
1760
INSTR_T
1761
bfin_gen_cc2dreg (int op, REG_T reg)
1762
{
1763
  INIT (CC2dreg);
1764
 
1765
  ASSIGN (op);
1766
  ASSIGN_R (reg);
1767
 
1768
  return GEN_OPCODE16 ();
1769
}
1770
 
1771
INSTR_T
1772
bfin_gen_progctrl (int prgfunc, int poprnd)
1773
{
1774
  INIT (ProgCtrl);
1775
 
1776
  ASSIGN (prgfunc);
1777
  ASSIGN (poprnd);
1778
 
1779
  return GEN_OPCODE16 ();
1780
}
1781
 
1782
INSTR_T
1783
bfin_gen_cactrl (REG_T reg, int a, int op)
1784
{
1785
  INIT (CaCTRL);
1786
 
1787
  ASSIGN_R (reg);
1788
  ASSIGN (a);
1789
  ASSIGN (op);
1790
 
1791
  return GEN_OPCODE16 ();
1792
}
1793
 
1794
INSTR_T
1795
bfin_gen_pushpopmultiple (int dr, int pr, int d, int p, int W)
1796
{
1797
  INIT (PushPopMultiple);
1798
 
1799
  ASSIGN (dr);
1800
  ASSIGN (pr);
1801
  ASSIGN (d);
1802
  ASSIGN (p);
1803
  ASSIGN (W);
1804
 
1805
  return GEN_OPCODE16 ();
1806
}
1807
 
1808
INSTR_T
1809
bfin_gen_pushpopreg (REG_T reg, int W)
1810
{
1811
  int grp;
1812
  INIT (PushPopReg);
1813
 
1814
  ASSIGN_R (reg);
1815
  grp = (GROUP (reg));
1816
  ASSIGN (grp);
1817
  ASSIGN (W);
1818
 
1819
  return GEN_OPCODE16 ();
1820
}
1821
 
1822
/* Pseudo Debugging Support.  */
1823
 
1824
INSTR_T
1825
bfin_gen_pseudodbg (int fn, int reg, int grp)
1826
{
1827
  INIT (PseudoDbg);
1828
 
1829
  ASSIGN (fn);
1830
  ASSIGN (reg);
1831
  ASSIGN (grp);
1832
 
1833
  return GEN_OPCODE16 ();
1834
}
1835
 
1836
INSTR_T
1837
bfin_gen_pseudodbg_assert (int dbgop, REG_T regtest, int expected)
1838
{
1839
  INIT (PseudoDbg_Assert);
1840
 
1841
  ASSIGN (dbgop);
1842
  ASSIGN_R (regtest);
1843
  ASSIGN (expected);
1844
 
1845
  return GEN_OPCODE32 ();
1846
}
1847
 
1848
/* Multiple instruction generation.  */
1849
 
1850
INSTR_T
1851
bfin_gen_multi_instr (INSTR_T dsp32, INSTR_T dsp16_grp1, INSTR_T dsp16_grp2)
1852
{
1853
  INSTR_T walk;
1854
 
1855
  /* If it's a 0, convert into MNOP. */
1856
  if (dsp32)
1857
    {
1858
      walk = dsp32->next;
1859
      SET_MULTI_INSTRUCTION_BIT (dsp32);
1860
    }
1861
  else
1862
    {
1863
      dsp32 = gencode (0xc803);
1864
      walk = gencode (0x1800);
1865
      dsp32->next = walk;
1866
    }
1867
 
1868
  if (!dsp16_grp1)
1869
    {
1870
      dsp16_grp1 = gencode (0x0000);
1871
    }
1872
 
1873
  if (!dsp16_grp2)
1874
    {
1875
      dsp16_grp2 = gencode (0x0000);
1876
    }
1877
 
1878
  walk->next = dsp16_grp1;
1879
  dsp16_grp1->next = dsp16_grp2;
1880
  dsp16_grp2->next = NULL_CODE;
1881
 
1882
  return dsp32;
1883
}
1884
 
1885
INSTR_T
1886
bfin_gen_loop (Expr_Node *expr, REG_T reg, int rop, REG_T preg)
1887
{
1888
  const char *loopsym;
1889
  char *lbeginsym, *lendsym;
1890
  Expr_Node_Value lbeginval, lendval;
1891
  Expr_Node *lbegin, *lend;
1892
 
1893
  loopsym = expr->value.s_value;
1894
  lbeginsym = (char *) xmalloc (strlen (loopsym) + strlen ("__BEGIN") + 5);
1895
  lendsym = (char *) xmalloc (strlen (loopsym) + strlen ("__END") + 5);
1896
 
1897
  lbeginsym[0] = 0;
1898
  lendsym[0] = 0;
1899
 
1900
  strcat (lbeginsym, "L$L$");
1901
  strcat (lbeginsym, loopsym);
1902
  strcat (lbeginsym, "__BEGIN");
1903
 
1904
  strcat (lendsym, "L$L$");
1905
  strcat (lendsym, loopsym);
1906
  strcat (lendsym, "__END");
1907
 
1908
  lbeginval.s_value = lbeginsym;
1909
  lendval.s_value = lendsym;
1910
 
1911
  lbegin = Expr_Node_Create (Expr_Node_Reloc, lbeginval, NULL, NULL);
1912
  lend   = Expr_Node_Create (Expr_Node_Reloc, lendval, NULL, NULL);
1913
 
1914
  symbol_remove (symbol_find (loopsym), &symbol_rootP, &symbol_lastP);
1915
 
1916
  return bfin_gen_loopsetup(lbegin, reg, rop, lend, preg);
1917
}
1918
 
1919
bfd_boolean
1920
bfin_eol_in_insn (char *line)
1921
{
1922
   /* Allow a new-line to appear in the middle of a multi-issue instruction.  */
1923
 
1924
   char *temp = line;
1925
 
1926
  if (*line != '\n')
1927
    return FALSE;
1928
 
1929
  /* A semi-colon followed by a newline is always the end of a line.  */
1930
  if (line[-1] == ';')
1931
    return FALSE;
1932
 
1933
  if (line[-1] == '|')
1934
    return TRUE;
1935
 
1936
  /* If the || is on the next line, there might be leading whitespace.  */
1937
  temp++;
1938
  while (*temp == ' ' || *temp == '\t') temp++;
1939
 
1940
  if (*temp == '|')
1941
    return TRUE;
1942
 
1943
  return FALSE;
1944
}
1945
 
1946
bfd_boolean
1947
bfin_start_label (char *ptr)
1948
{
1949
  ptr--;
1950
  while (!ISSPACE (*ptr) && !is_end_of_line[(unsigned char) *ptr])
1951
    ptr--;
1952
 
1953
  ptr++;
1954
  if (*ptr == '(' || *ptr == '[')
1955
    return FALSE;
1956
 
1957
  return TRUE;
1958
}
1959
 
1960
int
1961
bfin_force_relocation (struct fix *fixp)
1962
{
1963
  if (fixp->fx_r_type ==BFD_RELOC_BFIN_16_LOW
1964
      || fixp->fx_r_type == BFD_RELOC_BFIN_16_HIGH)
1965
    return TRUE;
1966
 
1967
  return generic_force_reloc (fixp);
1968
}

powered by: WebSVN 2.1.0

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