5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23 package jdk.vm.ci.code;
24
25 import java.nio.*;
26 import java.util.*;
27
28 import jdk.vm.ci.code.Register.RegisterCategory;
29 import jdk.vm.ci.meta.*;
30
31 /**
32 * Represents a CPU architecture, including information such as its endianness, CPU registers, word
33 * width, etc.
34 */
35 public abstract class Architecture {
36
37 /**
38 * The number of entries required in a {@link ReferenceMap} covering all the registers that may
39 * store references. The index of a register in the reference map is given by
40 * {@link Register#getReferenceMapIndex()}.
41 */
42 private final int registerReferenceMapSize;
43
44 /**
45 * The architecture specific type of a native word.
46 */
47 private final PlatformKind wordKind;
48
49 /**
50 * The name of this architecture (e.g. "AMD64", "SPARCv9").
51 */
52 private final String name;
53
54 /**
55 * Array of all available registers on this architecture. The index of each register in this
56 * array is equal to its {@linkplain Register#number number}.
57 */
58 private final Register[] registers;
59
60 /**
61 * The byte ordering can be either little or big endian.
62 */
63 private final ByteOrder byteOrder;
64
68 private final boolean unalignedMemoryAccess;
69
70 /**
71 * Mask of the barrier constants denoting the barriers that are not required to be explicitly
72 * inserted under this architecture.
73 */
74 private final int implicitMemoryBarriers;
75
76 /**
77 * Offset in bytes from the beginning of a call instruction to the displacement.
78 */
79 private final int machineCodeCallDisplacementOffset;
80
81 /**
82 * The size of the return address pushed to the stack by a call instruction. A value of 0
83 * denotes that call linkage uses registers instead (e.g. SPARC).
84 */
85 private final int returnAddressSize;
86
87 protected Architecture(String name, PlatformKind wordKind, ByteOrder byteOrder, boolean unalignedMemoryAccess, Register[] registers, int implicitMemoryBarriers, int nativeCallDisplacementOffset,
88 int registerReferenceMapSize, int returnAddressSize) {
89 this.name = name;
90 this.registers = registers;
91 this.wordKind = wordKind;
92 this.byteOrder = byteOrder;
93 this.unalignedMemoryAccess = unalignedMemoryAccess;
94 this.implicitMemoryBarriers = implicitMemoryBarriers;
95 this.machineCodeCallDisplacementOffset = nativeCallDisplacementOffset;
96 this.registerReferenceMapSize = registerReferenceMapSize;
97 this.returnAddressSize = returnAddressSize;
98 }
99
100 /**
101 * Converts this architecture to a string.
102 *
103 * @return the string representation of this architecture
104 */
105 @Override
106 public final String toString() {
107 return getName().toLowerCase();
108 }
109
110 public int getRegisterReferenceMapSize() {
111 return registerReferenceMapSize;
112 }
113
114 /**
115 * Gets the natural size of words (typically registers and pointers) of this architecture, in
116 * bytes.
117 */
118 public int getWordSize() {
119 return wordKind.getSizeInBytes();
120 }
121
122 public PlatformKind getWordKind() {
123 return wordKind;
124 }
125
126 /**
127 * Gets the name of this architecture.
128 */
129 public String getName() {
130 return name;
131 }
132
133 /**
134 * Gets an array of all available registers on this architecture. The index of each register in
135 * this array is equal to its {@linkplain Register#number number}.
136 */
137 public Register[] getRegisters() {
138 return registers.clone();
139 }
140
141 public ByteOrder getByteOrder() {
142 return byteOrder;
143 }
144
145 /**
146 * @return true if the architecture supports unaligned memory accesses.
147 */
148 public boolean supportsUnalignedMemoryAccess() {
149 return unalignedMemoryAccess;
150 }
151
152 /**
153 * Gets the size of the return address pushed to the stack by a call instruction. A value of 0
154 * denotes that call linkage uses registers instead.
155 */
156 public int getReturnAddressSize() {
157 return returnAddressSize;
158 }
159
160 /**
190 * @return the largest kind that can be stored in a register {@code category}
191 */
192 public abstract PlatformKind getLargestStorableKind(RegisterCategory category);
193
194 /**
195 * Return the {@link PlatformKind} that is used to store values of a given {@link JavaKind}.
196 */
197 public abstract PlatformKind getPlatformKind(JavaKind javaKind);
198
199 @Override
200 public final boolean equals(Object obj) {
201 if (obj == this) {
202 return true;
203 }
204 if (obj instanceof Architecture) {
205 Architecture that = (Architecture) obj;
206 if (this.name.equals(that.name)) {
207 assert this.byteOrder.equals(that.byteOrder);
208 assert this.implicitMemoryBarriers == that.implicitMemoryBarriers;
209 assert this.machineCodeCallDisplacementOffset == that.machineCodeCallDisplacementOffset;
210 assert this.registerReferenceMapSize == that.registerReferenceMapSize;
211 assert Arrays.equals(this.registers, that.registers);
212 assert this.returnAddressSize == that.returnAddressSize;
213 assert this.unalignedMemoryAccess == that.unalignedMemoryAccess;
214 assert this.wordKind == that.wordKind;
215 return true;
216 }
217 }
218 return false;
219 }
220
221 @Override
222 public final int hashCode() {
223 return name.hashCode();
224 }
225 }
|
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23 package jdk.vm.ci.code;
24
25 import java.nio.ByteOrder;
26 import java.util.Arrays;
27
28 import jdk.vm.ci.code.Register.RegisterCategory;
29 import jdk.vm.ci.meta.JavaKind;
30 import jdk.vm.ci.meta.PlatformKind;
31
32 /**
33 * Represents a CPU architecture, including information such as its endianness, CPU registers, word
34 * width, etc.
35 */
36 public abstract class Architecture {
37
38 /**
39 * The architecture specific type of a native word.
40 */
41 private final PlatformKind wordKind;
42
43 /**
44 * The name of this architecture (e.g. "AMD64", "SPARCv9").
45 */
46 private final String name;
47
48 /**
49 * Array of all available registers on this architecture. The index of each register in this
50 * array is equal to its {@linkplain Register#number number}.
51 */
52 private final Register[] registers;
53
54 /**
55 * The byte ordering can be either little or big endian.
56 */
57 private final ByteOrder byteOrder;
58
62 private final boolean unalignedMemoryAccess;
63
64 /**
65 * Mask of the barrier constants denoting the barriers that are not required to be explicitly
66 * inserted under this architecture.
67 */
68 private final int implicitMemoryBarriers;
69
70 /**
71 * Offset in bytes from the beginning of a call instruction to the displacement.
72 */
73 private final int machineCodeCallDisplacementOffset;
74
75 /**
76 * The size of the return address pushed to the stack by a call instruction. A value of 0
77 * denotes that call linkage uses registers instead (e.g. SPARC).
78 */
79 private final int returnAddressSize;
80
81 protected Architecture(String name, PlatformKind wordKind, ByteOrder byteOrder, boolean unalignedMemoryAccess, Register[] registers, int implicitMemoryBarriers, int nativeCallDisplacementOffset,
82 int returnAddressSize) {
83 this.name = name;
84 this.registers = registers;
85 this.wordKind = wordKind;
86 this.byteOrder = byteOrder;
87 this.unalignedMemoryAccess = unalignedMemoryAccess;
88 this.implicitMemoryBarriers = implicitMemoryBarriers;
89 this.machineCodeCallDisplacementOffset = nativeCallDisplacementOffset;
90 this.returnAddressSize = returnAddressSize;
91 }
92
93 /**
94 * Converts this architecture to a string.
95 *
96 * @return the string representation of this architecture
97 */
98 @Override
99 public final String toString() {
100 return getName().toLowerCase();
101 }
102
103 /**
104 * Gets the natural size of words (typically registers and pointers) of this architecture, in
105 * bytes.
106 */
107 public int getWordSize() {
108 return wordKind.getSizeInBytes();
109 }
110
111 public PlatformKind getWordKind() {
112 return wordKind;
113 }
114
115 /**
116 * Gets the name of this architecture.
117 */
118 public String getName() {
119 return name;
120 }
121
122 /**
123 * Gets an array of all registers that exist on this architecture. This contains all registers
124 * that exist in the specification of this architecture. Not all of them may be available on
125 * this particular architecture instance. The index of each register in this array is equal to
126 * its {@linkplain Register#number number}.
127 */
128 public Register[] getRegisters() {
129 return registers.clone();
130 }
131
132 /**
133 * Gets an array of all registers available for storing values on this architecture. This may be
134 * a subset of {@link #getRegisters()}, depending on the capabilities of this particular CPU.
135 */
136 public Register[] getAvailableValueRegisters() {
137 return getRegisters();
138 }
139
140 public ByteOrder getByteOrder() {
141 return byteOrder;
142 }
143
144 /**
145 * @return true if the architecture supports unaligned memory accesses.
146 */
147 public boolean supportsUnalignedMemoryAccess() {
148 return unalignedMemoryAccess;
149 }
150
151 /**
152 * Gets the size of the return address pushed to the stack by a call instruction. A value of 0
153 * denotes that call linkage uses registers instead.
154 */
155 public int getReturnAddressSize() {
156 return returnAddressSize;
157 }
158
159 /**
189 * @return the largest kind that can be stored in a register {@code category}
190 */
191 public abstract PlatformKind getLargestStorableKind(RegisterCategory category);
192
193 /**
194 * Return the {@link PlatformKind} that is used to store values of a given {@link JavaKind}.
195 */
196 public abstract PlatformKind getPlatformKind(JavaKind javaKind);
197
198 @Override
199 public final boolean equals(Object obj) {
200 if (obj == this) {
201 return true;
202 }
203 if (obj instanceof Architecture) {
204 Architecture that = (Architecture) obj;
205 if (this.name.equals(that.name)) {
206 assert this.byteOrder.equals(that.byteOrder);
207 assert this.implicitMemoryBarriers == that.implicitMemoryBarriers;
208 assert this.machineCodeCallDisplacementOffset == that.machineCodeCallDisplacementOffset;
209 assert Arrays.equals(this.registers, that.registers);
210 assert this.returnAddressSize == that.returnAddressSize;
211 assert this.unalignedMemoryAccess == that.unalignedMemoryAccess;
212 assert this.wordKind == that.wordKind;
213 return true;
214 }
215 }
216 return false;
217 }
218
219 @Override
220 public final int hashCode() {
221 return name.hashCode();
222 }
223 }
|