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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [tools/] [external/] [asm/] [org/] [objectweb/] [asm/] [Type.java] - Blame information for rev 779

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 779 jeremybenn
/***
2
 * ASM: a very small and fast Java bytecode manipulation framework
3
 * Copyright (c) 2000-2005 INRIA, France Telecom
4
 * All rights reserved.
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
8
 * are met:
9
 * 1. Redistributions of source code must retain the above copyright
10
 *    notice, this list of conditions and the following disclaimer.
11
 * 2. Redistributions in binary form must reproduce the above copyright
12
 *    notice, this list of conditions and the following disclaimer in the
13
 *    documentation and/or other materials provided with the distribution.
14
 * 3. Neither the name of the copyright holders nor the names of its
15
 *    contributors may be used to endorse or promote products derived from
16
 *    this software without specific prior written permission.
17
 *
18
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28
 * THE POSSIBILITY OF SUCH DAMAGE.
29
 */
30
package org.objectweb.asm;
31
 
32
import java.lang.reflect.Method;
33
 
34
/**
35
 * A Java type. This class can be used to make it easier to manipulate type and
36
 * method descriptors.
37
 *
38
 * @author Eric Bruneton
39
 * @author Chris Nokleberg
40
 */
41
public class Type {
42
 
43
    /**
44
     * The sort of the <tt>void</tt> type. See {@link #getSort getSort}.
45
     */
46
    public final static int VOID = 0;
47
 
48
    /**
49
     * The sort of the <tt>boolean</tt> type. See {@link #getSort getSort}.
50
     */
51
    public final static int BOOLEAN = 1;
52
 
53
    /**
54
     * The sort of the <tt>char</tt> type. See {@link #getSort getSort}.
55
     */
56
    public final static int CHAR = 2;
57
 
58
    /**
59
     * The sort of the <tt>byte</tt> type. See {@link #getSort getSort}.
60
     */
61
    public final static int BYTE = 3;
62
 
63
    /**
64
     * The sort of the <tt>short</tt> type. See {@link #getSort getSort}.
65
     */
66
    public final static int SHORT = 4;
67
 
68
    /**
69
     * The sort of the <tt>int</tt> type. See {@link #getSort getSort}.
70
     */
71
    public final static int INT = 5;
72
 
73
    /**
74
     * The sort of the <tt>float</tt> type. See {@link #getSort getSort}.
75
     */
76
    public final static int FLOAT = 6;
77
 
78
    /**
79
     * The sort of the <tt>long</tt> type. See {@link #getSort getSort}.
80
     */
81
    public final static int LONG = 7;
82
 
83
    /**
84
     * The sort of the <tt>double</tt> type. See {@link #getSort getSort}.
85
     */
86
    public final static int DOUBLE = 8;
87
 
88
    /**
89
     * The sort of array reference types. See {@link #getSort getSort}.
90
     */
91
    public final static int ARRAY = 9;
92
 
93
    /**
94
     * The sort of object reference type. See {@link #getSort getSort}.
95
     */
96
    public final static int OBJECT = 10;
97
 
98
    /**
99
     * The <tt>void</tt> type.
100
     */
101
    public final static Type VOID_TYPE = new Type(VOID);
102
 
103
    /**
104
     * The <tt>boolean</tt> type.
105
     */
106
    public final static Type BOOLEAN_TYPE = new Type(BOOLEAN);
107
 
108
    /**
109
     * The <tt>char</tt> type.
110
     */
111
    public final static Type CHAR_TYPE = new Type(CHAR);
112
 
113
    /**
114
     * The <tt>byte</tt> type.
115
     */
116
    public final static Type BYTE_TYPE = new Type(BYTE);
117
 
118
    /**
119
     * The <tt>short</tt> type.
120
     */
121
    public final static Type SHORT_TYPE = new Type(SHORT);
122
 
123
    /**
124
     * The <tt>int</tt> type.
125
     */
126
    public final static Type INT_TYPE = new Type(INT);
127
 
128
    /**
129
     * The <tt>float</tt> type.
130
     */
131
    public final static Type FLOAT_TYPE = new Type(FLOAT);
132
 
133
    /**
134
     * The <tt>long</tt> type.
135
     */
136
    public final static Type LONG_TYPE = new Type(LONG);
137
 
138
    /**
139
     * The <tt>double</tt> type.
140
     */
141
    public final static Type DOUBLE_TYPE = new Type(DOUBLE);
142
 
143
    // ------------------------------------------------------------------------
144
    // Fields
145
    // ------------------------------------------------------------------------
146
 
147
    /**
148
     * The sort of this Java type.
149
     */
150
    private final int sort;
151
 
152
    /**
153
     * A buffer containing the descriptor of this Java type. This field is only
154
     * used for reference types.
155
     */
156
    private char[] buf;
157
 
158
    /**
159
     * The offset of the descriptor of this Java type in {@link #buf buf}. This
160
     * field is only used for reference types.
161
     */
162
    private int off;
163
 
164
    /**
165
     * The length of the descriptor of this Java type.
166
     */
167
    private int len;
168
 
169
    // ------------------------------------------------------------------------
170
    // Constructors
171
    // ------------------------------------------------------------------------
172
 
173
    /**
174
     * Constructs a primitive type.
175
     *
176
     * @param sort the sort of the primitive type to be constructed.
177
     */
178
    private Type(final int sort) {
179
        this.sort = sort;
180
        this.len = 1;
181
    }
182
 
183
    /**
184
     * Constructs a reference type.
185
     *
186
     * @param sort the sort of the reference type to be constructed.
187
     * @param buf a buffer containing the descriptor of the previous type.
188
     * @param off the offset of this descriptor in the previous buffer.
189
     * @param len the length of this descriptor.
190
     */
191
    private Type(final int sort, final char[] buf, final int off, final int len)
192
    {
193
        this.sort = sort;
194
        this.buf = buf;
195
        this.off = off;
196
        this.len = len;
197
    }
198
 
199
    /**
200
     * Returns the Java type corresponding to the given type descriptor.
201
     *
202
     * @param typeDescriptor a type descriptor.
203
     * @return the Java type corresponding to the given type descriptor.
204
     */
205
    public static Type getType(final String typeDescriptor) {
206
        return getType(typeDescriptor.toCharArray(), 0);
207
    }
208
 
209
    /**
210
     * Returns the Java type corresponding to the given class.
211
     *
212
     * @param c a class.
213
     * @return the Java type corresponding to the given class.
214
     */
215
    public static Type getType(final Class c) {
216
        if (c.isPrimitive()) {
217
            if (c == Integer.TYPE) {
218
                return INT_TYPE;
219
            } else if (c == Void.TYPE) {
220
                return VOID_TYPE;
221
            } else if (c == Boolean.TYPE) {
222
                return BOOLEAN_TYPE;
223
            } else if (c == Byte.TYPE) {
224
                return BYTE_TYPE;
225
            } else if (c == Character.TYPE) {
226
                return CHAR_TYPE;
227
            } else if (c == Short.TYPE) {
228
                return SHORT_TYPE;
229
            } else if (c == Double.TYPE) {
230
                return DOUBLE_TYPE;
231
            } else if (c == Float.TYPE) {
232
                return FLOAT_TYPE;
233
            } else /* if (c == Long.TYPE) */{
234
                return LONG_TYPE;
235
            }
236
        } else {
237
            return getType(getDescriptor(c));
238
        }
239
    }
240
 
241
    /**
242
     * Returns the Java types corresponding to the argument types of the given
243
     * method descriptor.
244
     *
245
     * @param methodDescriptor a method descriptor.
246
     * @return the Java types corresponding to the argument types of the given
247
     *         method descriptor.
248
     */
249
    public static Type[] getArgumentTypes(final String methodDescriptor) {
250
        char[] buf = methodDescriptor.toCharArray();
251
        int off = 1;
252
        int size = 0;
253
        while (true) {
254
            char car = buf[off++];
255
            if (car == ')') {
256
                break;
257
            } else if (car == 'L') {
258
                while (buf[off++] != ';') {
259
                }
260
                ++size;
261
            } else if (car != '[') {
262
                ++size;
263
            }
264
        }
265
        Type[] args = new Type[size];
266
        off = 1;
267
        size = 0;
268
        while (buf[off] != ')') {
269
            args[size] = getType(buf, off);
270
            off += args[size].len;
271
            size += 1;
272
        }
273
        return args;
274
    }
275
 
276
    /**
277
     * Returns the Java types corresponding to the argument types of the given
278
     * method.
279
     *
280
     * @param method a method.
281
     * @return the Java types corresponding to the argument types of the given
282
     *         method.
283
     */
284
    public static Type[] getArgumentTypes(final Method method) {
285
        Class[] classes = method.getParameterTypes();
286
        Type[] types = new Type[classes.length];
287
        for (int i = classes.length - 1; i >= 0; --i) {
288
            types[i] = getType(classes[i]);
289
        }
290
        return types;
291
    }
292
 
293
    /**
294
     * Returns the Java type corresponding to the return type of the given
295
     * method descriptor.
296
     *
297
     * @param methodDescriptor a method descriptor.
298
     * @return the Java type corresponding to the return type of the given
299
     *         method descriptor.
300
     */
301
    public static Type getReturnType(final String methodDescriptor) {
302
        char[] buf = methodDescriptor.toCharArray();
303
        return getType(buf, methodDescriptor.indexOf(')') + 1);
304
    }
305
 
306
    /**
307
     * Returns the Java type corresponding to the return type of the given
308
     * method.
309
     *
310
     * @param method a method.
311
     * @return the Java type corresponding to the return type of the given
312
     *         method.
313
     */
314
    public static Type getReturnType(final Method method) {
315
        return getType(method.getReturnType());
316
    }
317
 
318
    /**
319
     * Returns the Java type corresponding to the given type descriptor.
320
     *
321
     * @param buf a buffer containing a type descriptor.
322
     * @param off the offset of this descriptor in the previous buffer.
323
     * @return the Java type corresponding to the given type descriptor.
324
     */
325
    private static Type getType(final char[] buf, final int off) {
326
        int len;
327
        switch (buf[off]) {
328
            case 'V':
329
                return VOID_TYPE;
330
            case 'Z':
331
                return BOOLEAN_TYPE;
332
            case 'C':
333
                return CHAR_TYPE;
334
            case 'B':
335
                return BYTE_TYPE;
336
            case 'S':
337
                return SHORT_TYPE;
338
            case 'I':
339
                return INT_TYPE;
340
            case 'F':
341
                return FLOAT_TYPE;
342
            case 'J':
343
                return LONG_TYPE;
344
            case 'D':
345
                return DOUBLE_TYPE;
346
            case '[':
347
                len = 1;
348
                while (buf[off + len] == '[') {
349
                    ++len;
350
                }
351
                if (buf[off + len] == 'L') {
352
                    ++len;
353
                    while (buf[off + len] != ';') {
354
                        ++len;
355
                    }
356
                }
357
                return new Type(ARRAY, buf, off, len + 1);
358
            // case 'L':
359
            default:
360
                len = 1;
361
                while (buf[off + len] != ';') {
362
                    ++len;
363
                }
364
                return new Type(OBJECT, buf, off, len + 1);
365
        }
366
    }
367
 
368
    // ------------------------------------------------------------------------
369
    // Accessors
370
    // ------------------------------------------------------------------------
371
 
372
    /**
373
     * Returns the sort of this Java type.
374
     *
375
     * @return {@link #VOID VOID}, {@link #BOOLEAN BOOLEAN},
376
     *         {@link #CHAR CHAR}, {@link #BYTE BYTE}, {@link #SHORT SHORT},
377
     *         {@link #INT INT}, {@link #FLOAT FLOAT}, {@link #LONG LONG},
378
     *         {@link #DOUBLE DOUBLE}, {@link #ARRAY ARRAY} or
379
     *         {@link #OBJECT OBJECT}.
380
     */
381
    public int getSort() {
382
        return sort;
383
    }
384
 
385
    /**
386
     * Returns the number of dimensions of this array type. This method should
387
     * only be used for an array type.
388
     *
389
     * @return the number of dimensions of this array type.
390
     */
391
    public int getDimensions() {
392
        int i = 1;
393
        while (buf[off + i] == '[') {
394
            ++i;
395
        }
396
        return i;
397
    }
398
 
399
    /**
400
     * Returns the type of the elements of this array type. This method should
401
     * only be used for an array type.
402
     *
403
     * @return Returns the type of the elements of this array type.
404
     */
405
    public Type getElementType() {
406
        return getType(buf, off + getDimensions());
407
    }
408
 
409
    /**
410
     * Returns the name of the class corresponding to this type.
411
     *
412
     * @return the fully qualified name of the class corresponding to this type.
413
     */
414
    public String getClassName() {
415
        switch (sort) {
416
            case VOID:
417
                return "void";
418
            case BOOLEAN:
419
                return "boolean";
420
            case CHAR:
421
                return "char";
422
            case BYTE:
423
                return "byte";
424
            case SHORT:
425
                return "short";
426
            case INT:
427
                return "int";
428
            case FLOAT:
429
                return "float";
430
            case LONG:
431
                return "long";
432
            case DOUBLE:
433
                return "double";
434
            case ARRAY:
435
                StringBuffer b = new StringBuffer(getElementType().getClassName());
436
                for (int i = getDimensions(); i > 0; --i) {
437
                    b.append("[]");
438
                }
439
                return b.toString();
440
            // case OBJECT:
441
            default:
442
                return new String(buf, off + 1, len - 2).replace('/', '.');
443
        }
444
    }
445
 
446
    /**
447
     * Returns the internal name of the class corresponding to this object type.
448
     * The internal name of a class is its fully qualified name, where '.' are
449
     * replaced by '/'. This method should only be used for an object type.
450
     *
451
     * @return the internal name of the class corresponding to this object type.
452
     */
453
    public String getInternalName() {
454
        return new String(buf, off + 1, len - 2);
455
    }
456
 
457
    // ------------------------------------------------------------------------
458
    // Conversion to type descriptors
459
    // ------------------------------------------------------------------------
460
 
461
    /**
462
     * Returns the descriptor corresponding to this Java type.
463
     *
464
     * @return the descriptor corresponding to this Java type.
465
     */
466
    public String getDescriptor() {
467
        StringBuffer buf = new StringBuffer();
468
        getDescriptor(buf);
469
        return buf.toString();
470
    }
471
 
472
    /**
473
     * Returns the descriptor corresponding to the given argument and return
474
     * types.
475
     *
476
     * @param returnType the return type of the method.
477
     * @param argumentTypes the argument types of the method.
478
     * @return the descriptor corresponding to the given argument and return
479
     *         types.
480
     */
481
    public static String getMethodDescriptor(
482
        final Type returnType,
483
        final Type[] argumentTypes)
484
    {
485
        StringBuffer buf = new StringBuffer();
486
        buf.append('(');
487
        for (int i = 0; i < argumentTypes.length; ++i) {
488
            argumentTypes[i].getDescriptor(buf);
489
        }
490
        buf.append(')');
491
        returnType.getDescriptor(buf);
492
        return buf.toString();
493
    }
494
 
495
    /**
496
     * Appends the descriptor corresponding to this Java type to the given
497
     * string buffer.
498
     *
499
     * @param buf the string buffer to which the descriptor must be appended.
500
     */
501
    private void getDescriptor(final StringBuffer buf) {
502
        switch (sort) {
503
            case VOID:
504
                buf.append('V');
505
                return;
506
            case BOOLEAN:
507
                buf.append('Z');
508
                return;
509
            case CHAR:
510
                buf.append('C');
511
                return;
512
            case BYTE:
513
                buf.append('B');
514
                return;
515
            case SHORT:
516
                buf.append('S');
517
                return;
518
            case INT:
519
                buf.append('I');
520
                return;
521
            case FLOAT:
522
                buf.append('F');
523
                return;
524
            case LONG:
525
                buf.append('J');
526
                return;
527
            case DOUBLE:
528
                buf.append('D');
529
                return;
530
            // case ARRAY:
531
            // case OBJECT:
532
            default:
533
                buf.append(this.buf, off, len);
534
        }
535
    }
536
 
537
    // ------------------------------------------------------------------------
538
    // Direct conversion from classes to type descriptors,
539
    // without intermediate Type objects
540
    // ------------------------------------------------------------------------
541
 
542
    /**
543
     * Returns the internal name of the given class. The internal name of a
544
     * class is its fully qualified name, where '.' are replaced by '/'.
545
     *
546
     * @param c an object class.
547
     * @return the internal name of the given class.
548
     */
549
    public static String getInternalName(final Class c) {
550
        return c.getName().replace('.', '/');
551
    }
552
 
553
    /**
554
     * Returns the descriptor corresponding to the given Java type.
555
     *
556
     * @param c an object class, a primitive class or an array class.
557
     * @return the descriptor corresponding to the given class.
558
     */
559
    public static String getDescriptor(final Class c) {
560
        StringBuffer buf = new StringBuffer();
561
        getDescriptor(buf, c);
562
        return buf.toString();
563
    }
564
 
565
    /**
566
     * Returns the descriptor corresponding to the given method.
567
     *
568
     * @param m a {@link Method Method} object.
569
     * @return the descriptor of the given method.
570
     */
571
    public static String getMethodDescriptor(final Method m) {
572
        Class[] parameters = m.getParameterTypes();
573
        StringBuffer buf = new StringBuffer();
574
        buf.append('(');
575
        for (int i = 0; i < parameters.length; ++i) {
576
            getDescriptor(buf, parameters[i]);
577
        }
578
        buf.append(')');
579
        getDescriptor(buf, m.getReturnType());
580
        return buf.toString();
581
    }
582
 
583
    /**
584
     * Appends the descriptor of the given class to the given string buffer.
585
     *
586
     * @param buf the string buffer to which the descriptor must be appended.
587
     * @param c the class whose descriptor must be computed.
588
     */
589
    private static void getDescriptor(final StringBuffer buf, final Class c) {
590
        Class d = c;
591
        while (true) {
592
            if (d.isPrimitive()) {
593
                char car;
594
                if (d == Integer.TYPE) {
595
                    car = 'I';
596
                } else if (d == Void.TYPE) {
597
                    car = 'V';
598
                } else if (d == Boolean.TYPE) {
599
                    car = 'Z';
600
                } else if (d == Byte.TYPE) {
601
                    car = 'B';
602
                } else if (d == Character.TYPE) {
603
                    car = 'C';
604
                } else if (d == Short.TYPE) {
605
                    car = 'S';
606
                } else if (d == Double.TYPE) {
607
                    car = 'D';
608
                } else if (d == Float.TYPE) {
609
                    car = 'F';
610
                } else /* if (d == Long.TYPE) */{
611
                    car = 'J';
612
                }
613
                buf.append(car);
614
                return;
615
            } else if (d.isArray()) {
616
                buf.append('[');
617
                d = d.getComponentType();
618
            } else {
619
                buf.append('L');
620
                String name = d.getName();
621
                int len = name.length();
622
                for (int i = 0; i < len; ++i) {
623
                    char car = name.charAt(i);
624
                    buf.append(car == '.' ? '/' : car);
625
                }
626
                buf.append(';');
627
                return;
628
            }
629
        }
630
    }
631
 
632
    // ------------------------------------------------------------------------
633
    // Corresponding size and opcodes
634
    // ------------------------------------------------------------------------
635
 
636
    /**
637
     * Returns the size of values of this type.
638
     *
639
     * @return the size of values of this type, i.e., 2 for <tt>long</tt> and
640
     *         <tt>double</tt>, and 1 otherwise.
641
     */
642
    public int getSize() {
643
        return (sort == LONG || sort == DOUBLE ? 2 : 1);
644
    }
645
 
646
    /**
647
     * Returns a JVM instruction opcode adapted to this Java type.
648
     *
649
     * @param opcode a JVM instruction opcode. This opcode must be one of ILOAD,
650
     *        ISTORE, IALOAD, IASTORE, IADD, ISUB, IMUL, IDIV, IREM, INEG, ISHL,
651
     *        ISHR, IUSHR, IAND, IOR, IXOR and IRETURN.
652
     * @return an opcode that is similar to the given opcode, but adapted to
653
     *         this Java type. For example, if this type is <tt>float</tt> and
654
     *         <tt>opcode</tt> is IRETURN, this method returns FRETURN.
655
     */
656
    public int getOpcode(final int opcode) {
657
        if (opcode == Opcodes.IALOAD || opcode == Opcodes.IASTORE) {
658
            switch (sort) {
659
                case BOOLEAN:
660
                case BYTE:
661
                    return opcode + 5;
662
                case CHAR:
663
                    return opcode + 6;
664
                case SHORT:
665
                    return opcode + 7;
666
                case INT:
667
                    return opcode;
668
                case FLOAT:
669
                    return opcode + 2;
670
                case LONG:
671
                    return opcode + 1;
672
                case DOUBLE:
673
                    return opcode + 3;
674
                // case ARRAY:
675
                // case OBJECT:
676
                default:
677
                    return opcode + 4;
678
            }
679
        } else {
680
            switch (sort) {
681
                case VOID:
682
                    return opcode + 5;
683
                case BOOLEAN:
684
                case CHAR:
685
                case BYTE:
686
                case SHORT:
687
                case INT:
688
                    return opcode;
689
                case FLOAT:
690
                    return opcode + 2;
691
                case LONG:
692
                    return opcode + 1;
693
                case DOUBLE:
694
                    return opcode + 3;
695
                // case ARRAY:
696
                // case OBJECT:
697
                default:
698
                    return opcode + 4;
699
            }
700
        }
701
    }
702
 
703
    // ------------------------------------------------------------------------
704
    // Equals, hashCode and toString
705
    // ------------------------------------------------------------------------
706
 
707
    /**
708
     * Tests if the given object is equal to this type.
709
     *
710
     * @param o the object to be compared to this type.
711
     * @return <tt>true</tt> if the given object is equal to this type.
712
     */
713
    public boolean equals(final Object o) {
714
        if (this == o) {
715
            return true;
716
        }
717
        if (o == null || !(o instanceof Type)) {
718
            return false;
719
        }
720
        Type t = (Type) o;
721
        if (sort != t.sort) {
722
            return false;
723
        }
724
        if (sort == Type.OBJECT || sort == Type.ARRAY) {
725
            if (len != t.len) {
726
                return false;
727
            }
728
            for (int i = off, j = t.off, end = i + len; i < end; i++, j++) {
729
                if (buf[i] != t.buf[j]) {
730
                    return false;
731
                }
732
            }
733
        }
734
        return true;
735
    }
736
 
737
    /**
738
     * Returns a hash code value for this type.
739
     *
740
     * @return a hash code value for this type.
741
     */
742
    public int hashCode() {
743
        int hc = 13 * sort;
744
        if (sort == Type.OBJECT || sort == Type.ARRAY) {
745
            for (int i = off, end = i + len; i < end; i++) {
746
                hc = 17 * (hc + buf[i]);
747
            }
748
        }
749
        return hc;
750
    }
751
 
752
    /**
753
     * Returns a string representation of this type.
754
     *
755
     * @return the descriptor of this type.
756
     */
757
    public String toString() {
758
        return getDescriptor();
759
    }
760
}

powered by: WebSVN 2.1.0

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