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

Subversion Repositories open8_urisc

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

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

Line No. Rev Author Line
1 16 khays
/* tc-moxie.c -- Assemble code for moxie
2
   Copyright 2009
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
19
   the Free Software Foundation, 51 Franklin Street - Fifth Floor,
20
   Boston, MA 02110-1301, USA.  */
21
 
22
/* Contributed by Anthony Green <green@moxielogic.com>.  */
23
 
24
#include "as.h"
25
#include "safe-ctype.h"
26
#include "opcode/moxie.h"
27
#include "elf/moxie.h"
28
 
29
extern const moxie_opc_info_t moxie_opc_info[128];
30
 
31
const char comment_chars[]        = "#";
32
const char line_separator_chars[] = ";";
33
const char line_comment_chars[]   = "#";
34
 
35
static int pending_reloc;
36
static struct hash_control *opcode_hash_control;
37
 
38
const pseudo_typeS md_pseudo_table[] =
39
{
40
  {0, 0, 0}
41
};
42
 
43
const char FLT_CHARS[] = "rRsSfFdDxXpP";
44
const char EXP_CHARS[] = "eE";
45
 
46
static int md_chars_to_number (char *val, int n);
47
 
48
void
49
md_operand (expressionS *op __attribute__((unused)))
50
{
51
  /* Empty for now. */
52
}
53
 
54
/* This function is called once, at assembler startup time.  It sets
55
   up the hash table with all the opcodes in it, and also initializes
56
   some aliases for compatibility with other assemblers.  */
57
 
58
void
59
md_begin (void)
60
{
61
  int count;
62
  const moxie_opc_info_t *opcode;
63
  opcode_hash_control = hash_new ();
64
 
65
  /* Insert names into hash table.  */
66
  for (count = 0, opcode = moxie_form1_opc_info; count++ < 64; opcode++)
67
    hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
68
 
69
  for (count = 0, opcode = moxie_form2_opc_info; count++ < 4; opcode++)
70
    hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
71
 
72
  for (count = 0, opcode = moxie_form3_opc_info; count++ < 10; opcode++)
73
    hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
74
 
75
  bfd_set_arch_mach (stdoutput, TARGET_ARCH, 0);
76
}
77
 
78
/* Parse an expression and then restore the input line pointer.  */
79
 
80
static char *
81
parse_exp_save_ilp (char *s, expressionS *op)
82
{
83
  char *save = input_line_pointer;
84
 
85
  input_line_pointer = s;
86
  expression (op);
87
  s = input_line_pointer;
88
  input_line_pointer = save;
89
  return s;
90
}
91
 
92
static int
93
parse_register_operand (char **ptr)
94
{
95
  int reg;
96
  char *s = *ptr;
97
 
98
  if (*s != '$')
99
    {
100
      as_bad (_("expecting register"));
101
      ignore_rest_of_line ();
102
      return -1;
103
    }
104
  if (s[1] == 'f' && s[2] == 'p')
105
    {
106
      *ptr += 3;
107
      return 0;
108
    }
109
  if (s[1] == 's' && s[2] == 'p')
110
    {
111
      *ptr += 3;
112
      return 1;
113
    }
114
  if (s[1] == 'r')
115
    {
116
      reg = s[2] - '0';
117
      if ((reg < 0) || (reg > 9))
118
        {
119
          as_bad (_("illegal register number"));
120
          ignore_rest_of_line ();
121
          return -1;
122
        }
123
      if (reg == 1)
124
        {
125
          int r2 = s[3] - '0';
126
          if ((r2 >= 0) && (r2 <= 3))
127
            {
128
              reg = 10 + r2;
129
              *ptr += 1;
130
            }
131
        }
132
    }
133
  else
134
    {
135
      as_bad (_("illegal register number"));
136
      ignore_rest_of_line ();
137
      return -1;
138
    }
139
 
140
  *ptr += 3;
141
 
142
  return reg + 2;
143
}
144
 
145
/* This is the guts of the machine-dependent assembler.  STR points to
146
   a machine dependent instruction.  This function is supposed to emit
147
   the frags/bytes it assembles to.  */
148
 
149
void
150
md_assemble (char *str)
151
{
152
  char *op_start;
153
  char *op_end;
154
 
155
  moxie_opc_info_t *opcode;
156
  char *p;
157
  char pend;
158
 
159
  unsigned short iword = 0;
160
 
161
  int nlen = 0;
162
 
163
  /* Drop leading whitespace.  */
164
  while (*str == ' ')
165
    str++;
166
 
167
  /* Find the op code end.  */
168
  op_start = str;
169
  for (op_end = str;
170
       *op_end && !is_end_of_line[*op_end & 0xff] && *op_end != ' ';
171
       op_end++)
172
    nlen++;
173
 
174
  pend = *op_end;
175
  *op_end = 0;
176
 
177
  if (nlen == 0)
178
    as_bad (_("can't find opcode "));
179
  opcode = (moxie_opc_info_t *) hash_find (opcode_hash_control, op_start);
180
  *op_end = pend;
181
 
182
  if (opcode == NULL)
183
    {
184
      as_bad (_("unknown opcode %s"), op_start);
185
      return;
186
    }
187
 
188
  p = frag_more (2);
189
 
190
  switch (opcode->itype)
191
    {
192
    case MOXIE_F2_A8V:
193
      iword = (1<<15) | (opcode->opcode << 12);
194
      while (ISSPACE (*op_end))
195
        op_end++;
196
      {
197
        expressionS arg;
198
        int reg;
199
        reg = parse_register_operand (&op_end);
200
        iword += (reg << 8);
201
        if (*op_end != ',')
202
          as_warn (_("expecting comma delimited register operands"));
203
        op_end++;
204
        op_end = parse_exp_save_ilp (op_end, &arg);
205
        fix_new_exp (frag_now,
206
                     ((p+1) - frag_now->fr_literal),
207
                     1,
208
                     &arg,
209
                     0,
210
                     BFD_RELOC_8);
211
      }
212
      break;
213
    case MOXIE_F1_AB:
214
      iword = opcode->opcode << 8;
215
      while (ISSPACE (*op_end))
216
        op_end++;
217
      {
218
        int dest, src;
219
        dest = parse_register_operand (&op_end);
220
        if (*op_end != ',')
221
          as_warn (_("expecting comma delimited register operands"));
222
        op_end++;
223
        src  = parse_register_operand (&op_end);
224
        iword += (dest << 4) + src;
225
        while (ISSPACE (*op_end))
226
          op_end++;
227
        if (*op_end != 0)
228
          as_warn (_("extra stuff on line ignored"));
229
      }
230
      break;
231
    case MOXIE_F1_A4:
232
      iword = opcode->opcode << 8;
233
      while (ISSPACE (*op_end))
234
        op_end++;
235
      {
236
        expressionS arg;
237
        char *where;
238
        int regnum;
239
 
240
        regnum = parse_register_operand (&op_end);
241
        while (ISSPACE (*op_end))
242
          op_end++;
243
 
244
        iword += (regnum << 4);
245
 
246
        if (*op_end != ',')
247
          {
248
            as_bad (_("expecting comma delimited operands"));
249
            ignore_rest_of_line ();
250
            return;
251
          }
252
        op_end++;
253
 
254
        op_end = parse_exp_save_ilp (op_end, &arg);
255
        where = frag_more (4);
256
        fix_new_exp (frag_now,
257
                     (where - frag_now->fr_literal),
258
                     4,
259
                     &arg,
260
                     0,
261
                     BFD_RELOC_32);
262
      }
263
      break;
264
    case MOXIE_F1_M:
265
    case MOXIE_F1_4:
266
      iword = opcode->opcode << 8;
267
      while (ISSPACE (*op_end))
268
        op_end++;
269
      {
270
        expressionS arg;
271
        char *where;
272
 
273
        op_end = parse_exp_save_ilp (op_end, &arg);
274
        where = frag_more (4);
275
        fix_new_exp (frag_now,
276
                     (where - frag_now->fr_literal),
277
                     4,
278
                     &arg,
279
                     0,
280
                     BFD_RELOC_32);
281
      }
282
      break;
283
    case MOXIE_F1_NARG:
284
      iword = opcode->opcode << 8;
285
      while (ISSPACE (*op_end))
286
        op_end++;
287
      if (*op_end != 0)
288
        as_warn (_("extra stuff on line ignored"));
289
      break;
290
    case MOXIE_F1_A:
291
      iword = opcode->opcode << 8;
292
      while (ISSPACE (*op_end))
293
        op_end++;
294
      {
295
        int reg;
296
        reg = parse_register_operand (&op_end);
297
        while (ISSPACE (*op_end))
298
          op_end++;
299
        if (*op_end != 0)
300
          as_warn (_("extra stuff on line ignored"));
301
        iword += (reg << 4);
302
      }
303
      break;
304
    case MOXIE_F1_ABi:
305
      iword = opcode->opcode << 8;
306
      while (ISSPACE (*op_end))
307
        op_end++;
308
      {
309
        int a, b;
310
        a = parse_register_operand (&op_end);
311
        if (*op_end != ',')
312
          as_warn (_("expecting comma delimited register operands"));
313
        op_end++;
314
        if (*op_end != '(')
315
          {
316
            as_bad (_("expecting indirect register `($rA)'"));
317
            ignore_rest_of_line ();
318
            return;
319
          }
320
        op_end++;
321
        b = parse_register_operand (&op_end);
322
        if (*op_end != ')')
323
          {
324
            as_bad (_("missing closing parenthesis"));
325
            ignore_rest_of_line ();
326
            return;
327
          }
328
        op_end++;
329
        iword += (a << 4) + b;
330
        while (ISSPACE (*op_end))
331
          op_end++;
332
        if (*op_end != 0)
333
          as_warn (_("extra stuff on line ignored"));
334
      }
335
      break;
336
    case MOXIE_F1_AiB:
337
      iword = opcode->opcode << 8;
338
      while (ISSPACE (*op_end))
339
        op_end++;
340
      {
341
        int a, b;
342
        if (*op_end != '(')
343
          {
344
            as_bad (_("expecting indirect register `($rA)'"));
345
            ignore_rest_of_line ();
346
            return;
347
          }
348
        op_end++;
349
        a = parse_register_operand (&op_end);
350
        if (*op_end != ')')
351
          {
352
            as_bad (_("missing closing parenthesis"));
353
            ignore_rest_of_line ();
354
            return;
355
          }
356
        op_end++;
357
        if (*op_end != ',')
358
          as_warn (_("expecting comma delimited register operands"));
359
        op_end++;
360
        b = parse_register_operand (&op_end);
361
        iword += (a << 4) + b;
362
        while (ISSPACE (*op_end))
363
          op_end++;
364
        if (*op_end != 0)
365
          as_warn (_("extra stuff on line ignored"));
366
      }
367
      break;
368
    case MOXIE_F1_4A:
369
      iword = opcode->opcode << 8;
370
      while (ISSPACE (*op_end))
371
        op_end++;
372
      {
373
        expressionS arg;
374
        char *where;
375
        int a;
376
 
377
        op_end = parse_exp_save_ilp (op_end, &arg);
378
        where = frag_more (4);
379
        fix_new_exp (frag_now,
380
                     (where - frag_now->fr_literal),
381
                     4,
382
                     &arg,
383
                     0,
384
                     BFD_RELOC_32);
385
 
386
        if (*op_end != ',')
387
          {
388
            as_bad (_("expecting comma delimited operands"));
389
            ignore_rest_of_line ();
390
            return;
391
          }
392
        op_end++;
393
 
394
        a = parse_register_operand (&op_end);
395
        while (ISSPACE (*op_end))
396
          op_end++;
397
        if (*op_end != 0)
398
          as_warn (_("extra stuff on line ignored"));
399
 
400
        iword += (a << 4);
401
      }
402
      break;
403
    case MOXIE_F1_ABi4:
404
      iword = opcode->opcode << 8;
405
      while (ISSPACE (*op_end))
406
        op_end++;
407
      {
408
        expressionS arg;
409
        char *offset;
410
        int a, b;
411
 
412
        a = parse_register_operand (&op_end);
413
        while (ISSPACE (*op_end))
414
          op_end++;
415
 
416
        if (*op_end != ',')
417
          {
418
            as_bad (_("expecting comma delimited operands"));
419
            ignore_rest_of_line ();
420
            return;
421
          }
422
        op_end++;
423
 
424
        op_end = parse_exp_save_ilp (op_end, &arg);
425
        offset = frag_more (4);
426
        fix_new_exp (frag_now,
427
                     (offset - frag_now->fr_literal),
428
                     4,
429
                     &arg,
430
                     0,
431
                     BFD_RELOC_32);
432
 
433
        if (*op_end != '(')
434
          {
435
            as_bad (_("expecting indirect register `($rX)'"));
436
            ignore_rest_of_line ();
437
            return;
438
          }
439
        op_end++;
440
        b = parse_register_operand (&op_end);
441
        if (*op_end != ')')
442
          {
443
            as_bad (_("missing closing parenthesis"));
444
            ignore_rest_of_line ();
445
            return;
446
          }
447
        op_end++;
448
 
449
        while (ISSPACE (*op_end))
450
          op_end++;
451
        if (*op_end != 0)
452
          as_warn (_("extra stuff on line ignored"));
453
 
454
        iword += (a << 4) + b;
455
      }
456
      break;
457
    case MOXIE_F1_AiB4:
458
      iword = opcode->opcode << 8;
459
      while (ISSPACE (*op_end))
460
        op_end++;
461
      {
462
        expressionS arg;
463
        char *offset;
464
        int a, b;
465
 
466
        op_end = parse_exp_save_ilp (op_end, &arg);
467
        offset = frag_more (4);
468
        fix_new_exp (frag_now,
469
                     (offset - frag_now->fr_literal),
470
                     4,
471
                     &arg,
472
                     0,
473
                     BFD_RELOC_32);
474
 
475
        if (*op_end != '(')
476
          {
477
            as_bad (_("expecting indirect register `($rX)'"));
478
            ignore_rest_of_line ();
479
            return;
480
          }
481
        op_end++;
482
        a = parse_register_operand (&op_end);
483
        if (*op_end != ')')
484
          {
485
            as_bad (_("missing closing parenthesis"));
486
            ignore_rest_of_line ();
487
            return;
488
          }
489
        op_end++;
490
 
491
        if (*op_end != ',')
492
          {
493
            as_bad (_("expecting comma delimited operands"));
494
            ignore_rest_of_line ();
495
            return;
496
          }
497
        op_end++;
498
 
499
        b = parse_register_operand (&op_end);
500
        while (ISSPACE (*op_end))
501
          op_end++;
502
 
503
        while (ISSPACE (*op_end))
504
          op_end++;
505
        if (*op_end != 0)
506
          as_warn (_("extra stuff on line ignored"));
507
 
508
        iword += (a << 4) + b;
509
      }
510
      break;
511
    case MOXIE_F2_NARG:
512
      iword = opcode->opcode << 12;
513
      while (ISSPACE (*op_end))
514
        op_end++;
515
      if (*op_end != 0)
516
        as_warn (_("extra stuff on line ignored"));
517
      break;
518
    case MOXIE_F3_PCREL:
519
      iword = (3<<14) | (opcode->opcode << 10);
520
      while (ISSPACE (*op_end))
521
        op_end++;
522
      {
523
        expressionS arg;
524
 
525
        op_end = parse_exp_save_ilp (op_end, &arg);
526
        fix_new_exp (frag_now,
527
                     (p - frag_now->fr_literal),
528
                     2,
529
                     &arg,
530
                     TRUE,
531
                     BFD_RELOC_MOXIE_10_PCREL);
532
      }
533
      break;
534
    default:
535
      abort ();
536
    }
537
 
538
  md_number_to_chars (p, iword, 2);
539
 
540
  while (ISSPACE (*op_end))
541
    op_end++;
542
 
543
  if (*op_end != 0)
544
    as_warn (_("extra stuff on line ignored"));
545
 
546
  if (pending_reloc)
547
    as_bad (_("Something forgot to clean up\n"));
548
}
549
 
550
/* Turn a string in input_line_pointer into a floating point constant
551
   of type type, and store the appropriate bytes in *LITP.  The number
552
   of LITTLENUMS emitted is stored in *SIZEP .  An error message is
553
   returned, or NULL on OK.  */
554
 
555
char *
556
md_atof (int type, char *litP, int *sizeP)
557
{
558
  int prec;
559
  LITTLENUM_TYPE words[4];
560
  char *t;
561
  int i;
562
 
563
  switch (type)
564
    {
565
    case 'f':
566
      prec = 2;
567
      break;
568
 
569
    case 'd':
570
      prec = 4;
571
      break;
572
 
573
    default:
574
      *sizeP = 0;
575
      return _("bad call to md_atof");
576
    }
577
 
578
  t = atof_ieee (input_line_pointer, type, words);
579
  if (t)
580
    input_line_pointer = t;
581
 
582
  *sizeP = prec * 2;
583
 
584
  for (i = prec - 1; i >= 0; i--)
585
    {
586
      md_number_to_chars (litP, (valueT) words[i], 2);
587
      litP += 2;
588
    }
589
 
590
  return NULL;
591
}
592
 
593
const char *md_shortopts = "";
594
 
595
struct option md_longopts[] =
596
{
597
  {NULL, no_argument, NULL, 0}
598
};
599
size_t md_longopts_size = sizeof (md_longopts);
600
 
601
/* We have no target specific options yet, so these next
602
   two functions are empty.  */
603
int
604
md_parse_option (int c ATTRIBUTE_UNUSED, char *arg ATTRIBUTE_UNUSED)
605
{
606
  return 0;
607
}
608
 
609
void
610
md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
611
{
612
}
613
 
614
/* Apply a fixup to the object file.  */
615
 
616
void
617
md_apply_fix (fixS *fixP ATTRIBUTE_UNUSED,
618
              valueT * valP ATTRIBUTE_UNUSED, segT seg ATTRIBUTE_UNUSED)
619
{
620
  char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
621
  long val = *valP;
622
  long newval;
623
  long max, min;
624
 
625
  max = min = 0;
626
  switch (fixP->fx_r_type)
627
    {
628
    case BFD_RELOC_32:
629
      *buf++ = val >> 24;
630
      *buf++ = val >> 16;
631
      *buf++ = val >> 8;
632
      *buf++ = val >> 0;
633
      break;
634
 
635
    case BFD_RELOC_16:
636
      *buf++ = val >> 8;
637
      *buf++ = val >> 0;
638
      break;
639
 
640
    case BFD_RELOC_8:
641
      *buf++ = val;
642
      break;
643
 
644
    case BFD_RELOC_MOXIE_10_PCREL:
645
      if (!val)
646
        break;
647
      if (val < -1024 || val > 1022)
648
        as_bad_where (fixP->fx_file, fixP->fx_line,
649
                      _("pcrel too far BFD_RELOC_MOXIE_10"));
650
      /* 11 bit offset even numbered, so we remove right bit.  */
651
      val >>= 1;
652
      newval = md_chars_to_number (buf, 2);
653
      newval |= val & 0x03ff;
654
      md_number_to_chars (buf, newval, 2);
655
      break;
656
 
657
    default:
658
      abort ();
659
    }
660
 
661
  if (max != 0 && (val < min || val > max))
662
    as_bad_where (fixP->fx_file, fixP->fx_line, _("offset out of range"));
663
 
664
  if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
665
    fixP->fx_done = 1;
666
}
667
 
668
/* Put number into target byte order (big endian).  */
669
 
670
void
671
md_number_to_chars (char *ptr, valueT use, int nbytes)
672
{
673
  number_to_chars_bigendian (ptr, use, nbytes);
674
}
675
 
676
/* Convert from target byte order to host byte order.  */
677
 
678
static int
679
md_chars_to_number (char *val, int n)
680
{
681
  int retval = 0;
682
 
683
  while (n--)
684
    {
685
      retval <<= 8;
686
      retval |= (*val++ & 255);
687
    }
688
 
689
  return retval;
690
}
691
 
692
/* Generate a machine-dependent relocation.  */
693
arelent *
694
tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
695
{
696
  arelent *relP;
697
  bfd_reloc_code_real_type code;
698
 
699
  switch (fixP->fx_r_type)
700
    {
701
    case BFD_RELOC_32:
702
      code = fixP->fx_r_type;
703
      break;
704
    case BFD_RELOC_MOXIE_10_PCREL:
705
      code = fixP->fx_r_type;
706
      break;
707
    default:
708
      as_bad_where (fixP->fx_file, fixP->fx_line,
709
                    _("Semantics error.  This type of operand can not be relocated, it must be an assembly-time constant"));
710
      return 0;
711
    }
712
 
713
  relP = xmalloc (sizeof (arelent));
714
  gas_assert (relP != 0);
715
  relP->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
716
  *relP->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
717
  relP->address = fixP->fx_frag->fr_address + fixP->fx_where;
718
 
719
  relP->addend = fixP->fx_offset;
720
 
721
  /* This is the standard place for KLUDGEs to work around bugs in
722
     bfd_install_relocation (first such note in the documentation
723
     appears with binutils-2.8).
724
 
725
     That function bfd_install_relocation does the wrong thing with
726
     putting stuff into the addend of a reloc (it should stay out) for a
727
     weak symbol.  The really bad thing is that it adds the
728
     "segment-relative offset" of the symbol into the reloc.  In this
729
     case, the reloc should instead be relative to the symbol with no
730
     other offset than the assembly code shows; and since the symbol is
731
     weak, any local definition should be ignored until link time (or
732
     thereafter).
733
     To wit:  weaksym+42  should be weaksym+42 in the reloc,
734
     not weaksym+(offset_from_segment_of_local_weaksym_definition)
735
 
736
     To "work around" this, we subtract the segment-relative offset of
737
     "known" weak symbols.  This evens out the extra offset.
738
 
739
     That happens for a.out but not for ELF, since for ELF,
740
     bfd_install_relocation uses the "special function" field of the
741
     howto, and does not execute the code that needs to be undone.  */
742
 
743
  if (OUTPUT_FLAVOR == bfd_target_aout_flavour
744
      && fixP->fx_addsy && S_IS_WEAK (fixP->fx_addsy)
745
      && ! bfd_is_und_section (S_GET_SEGMENT (fixP->fx_addsy)))
746
    {
747
      relP->addend -= S_GET_VALUE (fixP->fx_addsy);
748
    }
749
 
750
  relP->howto = bfd_reloc_type_lookup (stdoutput, code);
751
  if (! relP->howto)
752
    {
753
      const char *name;
754
 
755
      name = S_GET_NAME (fixP->fx_addsy);
756
      if (name == NULL)
757
        name = _("<unknown>");
758
      as_fatal (_("Cannot generate relocation type for symbol %s, code %s"),
759
                name, bfd_get_reloc_code_name (code));
760
    }
761
 
762
  return relP;
763
}
764
 
765
/* Decide from what point a pc-relative relocation is relative to,
766
   relative to the pc-relative fixup.  Er, relatively speaking.  */
767
long
768
md_pcrel_from (fixS *fixP)
769
{
770
  valueT addr = fixP->fx_where + fixP->fx_frag->fr_address;
771
 
772
  switch (fixP->fx_r_type)
773
    {
774
    case BFD_RELOC_32:
775
      return addr + 4;
776
    case BFD_RELOC_MOXIE_10_PCREL:
777
      return addr;
778
    default:
779
      abort ();
780
      return addr;
781
    }
782
}

powered by: WebSVN 2.1.0

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