comparison jvmci/jdk.vm.ci.code/src/jdk/vm/ci/code/Architecture.java @ 22672:1bbd4a7c274b

Rename jdk.internal.jvmci to jdk.vm.ci
author Tom Rodriguez <tom.rodriguez@oracle.com>
date Thu, 08 Oct 2015 17:28:41 -0700
parents jvmci/jdk.internal.jvmci.code/src/jdk/internal/jvmci/code/Architecture.java@3abba3d4aef1
children ef7d87db544a
comparison
equal deleted inserted replaced
22671:97f30e4d0e95 22672:1bbd4a7c274b
1 /*
2 * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
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 number of entries required in a {@link ReferenceMap} covering all the registers that may
40 * store references. The index of a register in the reference map is given by
41 * {@link Register#getReferenceMapIndex()}.
42 */
43 private final int registerReferenceMapSize;
44
45 /**
46 * The architecture specific type of a native word.
47 */
48 private final PlatformKind wordKind;
49
50 /**
51 * The name of this architecture (e.g. "AMD64", "SPARCv9").
52 */
53 private final String name;
54
55 /**
56 * Array of all available registers on this architecture. The index of each register in this
57 * array is equal to its {@linkplain Register#number number}.
58 */
59 private final Register[] registers;
60
61 /**
62 * The byte ordering can be either little or big endian.
63 */
64 private final ByteOrder byteOrder;
65
66 /**
67 * Whether the architecture supports unaligned memory accesses.
68 */
69 private final boolean unalignedMemoryAccess;
70
71 /**
72 * Mask of the barrier constants denoting the barriers that are not required to be explicitly
73 * inserted under this architecture.
74 */
75 private final int implicitMemoryBarriers;
76
77 /**
78 * Offset in bytes from the beginning of a call instruction to the displacement.
79 */
80 private final int machineCodeCallDisplacementOffset;
81
82 /**
83 * The size of the return address pushed to the stack by a call instruction. A value of 0
84 * denotes that call linkage uses registers instead (e.g. SPARC).
85 */
86 private final int returnAddressSize;
87
88 protected Architecture(String name, PlatformKind wordKind, ByteOrder byteOrder, boolean unalignedMemoryAccess, Register[] registers, int implicitMemoryBarriers, int nativeCallDisplacementOffset,
89 int registerReferenceMapSize, int returnAddressSize) {
90 this.name = name;
91 this.registers = registers;
92 this.wordKind = wordKind;
93 this.byteOrder = byteOrder;
94 this.unalignedMemoryAccess = unalignedMemoryAccess;
95 this.implicitMemoryBarriers = implicitMemoryBarriers;
96 this.machineCodeCallDisplacementOffset = nativeCallDisplacementOffset;
97 this.registerReferenceMapSize = registerReferenceMapSize;
98 this.returnAddressSize = returnAddressSize;
99 }
100
101 /**
102 * Converts this architecture to a string.
103 *
104 * @return the string representation of this architecture
105 */
106 @Override
107 public final String toString() {
108 return getName().toLowerCase();
109 }
110
111 public int getRegisterReferenceMapSize() {
112 return registerReferenceMapSize;
113 }
114
115 /**
116 * Gets the natural size of words (typically registers and pointers) of this architecture, in
117 * bytes.
118 */
119 public int getWordSize() {
120 return wordKind.getSizeInBytes();
121 }
122
123 public PlatformKind getWordKind() {
124 return wordKind;
125 }
126
127 /**
128 * Gets the name of this architecture.
129 */
130 public String getName() {
131 return name;
132 }
133
134 /**
135 * Gets an array of all registers that exist on this architecture. This contains all registers
136 * that exist in the specification of this architecture. Not all of them may be available on
137 * this particular architecture instance. The index of each register in this array is equal to
138 * its {@linkplain Register#number number}.
139 */
140 public Register[] getRegisters() {
141 return registers.clone();
142 }
143
144 /**
145 * Gets an array of all registers available for storing values on this architecture. This may be
146 * a subset of {@link #getRegisters()}, depending on the capabilities of this particular CPU.
147 */
148 public Register[] getAvailableValueRegisters() {
149 return getRegisters();
150 }
151
152 public ByteOrder getByteOrder() {
153 return byteOrder;
154 }
155
156 /**
157 * @return true if the architecture supports unaligned memory accesses.
158 */
159 public boolean supportsUnalignedMemoryAccess() {
160 return unalignedMemoryAccess;
161 }
162
163 /**
164 * Gets the size of the return address pushed to the stack by a call instruction. A value of 0
165 * denotes that call linkage uses registers instead.
166 */
167 public int getReturnAddressSize() {
168 return returnAddressSize;
169 }
170
171 /**
172 * Gets the offset in bytes from the beginning of a call instruction to the displacement.
173 */
174 public int getMachineCodeCallDisplacementOffset() {
175 return machineCodeCallDisplacementOffset;
176 }
177
178 /**
179 * Determines the barriers in a given barrier mask that are explicitly required on this
180 * architecture.
181 *
182 * @param barriers a mask of the barrier constants
183 * @return the value of {@code barriers} minus the barriers unnecessary on this architecture
184 */
185 public final int requiredBarriers(int barriers) {
186 return barriers & ~implicitMemoryBarriers;
187 }
188
189 /**
190 * Determine whether a kind can be stored in a register of a given category.
191 *
192 * @param category the category of the register
193 * @param kind the kind that should be stored in the register
194 */
195 public abstract boolean canStoreValue(RegisterCategory category, PlatformKind kind);
196
197 /**
198 * Return the largest kind that can be stored in a register of a given category.
199 *
200 * @param category the category of the register
201 * @return the largest kind that can be stored in a register {@code category}
202 */
203 public abstract PlatformKind getLargestStorableKind(RegisterCategory category);
204
205 /**
206 * Return the {@link PlatformKind} that is used to store values of a given {@link JavaKind}.
207 */
208 public abstract PlatformKind getPlatformKind(JavaKind javaKind);
209
210 @Override
211 public final boolean equals(Object obj) {
212 if (obj == this) {
213 return true;
214 }
215 if (obj instanceof Architecture) {
216 Architecture that = (Architecture) obj;
217 if (this.name.equals(that.name)) {
218 assert this.byteOrder.equals(that.byteOrder);
219 assert this.implicitMemoryBarriers == that.implicitMemoryBarriers;
220 assert this.machineCodeCallDisplacementOffset == that.machineCodeCallDisplacementOffset;
221 assert this.registerReferenceMapSize == that.registerReferenceMapSize;
222 assert Arrays.equals(this.registers, that.registers);
223 assert this.returnAddressSize == that.returnAddressSize;
224 assert this.unalignedMemoryAccess == that.unalignedMemoryAccess;
225 assert this.wordKind == that.wordKind;
226 return true;
227 }
228 }
229 return false;
230 }
231
232 @Override
233 public final int hashCode() {
234 return name.hashCode();
235 }
236 }