1 /* 2 * Copyright (c) 2009, 2019, 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 27 import jdk.vm.ci.code.Register.RegisterCategory; 28 import jdk.vm.ci.meta.JavaKind; 29 import jdk.vm.ci.meta.PlatformKind; 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 architecture specific type of a native word. 39 */ 40 private final PlatformKind wordKind; 41 42 /** 43 * The name of this architecture (e.g. "AMD64", "SPARCv9"). 44 */ 45 private final String name; 46 47 /** 48 * List of all available registers on this architecture. The index of each register in this list 49 * is equal to its {@linkplain Register#number number}. 50 */ 51 private final RegisterArray registers; 52 53 /** 54 * The byte ordering can be either little or big endian. 55 */ 56 private final ByteOrder byteOrder; 57 58 /** 59 * Whether the architecture supports unaligned memory accesses. 60 */ 61 private final boolean unalignedMemoryAccess; 62 63 /** 64 * Mask of the barrier constants denoting the barriers that are not required to be explicitly 65 * inserted under this architecture. 66 */ 67 private final int implicitMemoryBarriers; 68 69 /** 70 * Offset in bytes from the beginning of a call instruction to the displacement. 71 */ 72 private final int machineCodeCallDisplacementOffset; 73 74 /** 75 * The size of the return address pushed to the stack by a call instruction. A value of 0 76 * denotes that call linkage uses registers instead (e.g. SPARC). 77 */ 78 private final int returnAddressSize; 79 80 protected Architecture(String name, PlatformKind wordKind, ByteOrder byteOrder, boolean unalignedMemoryAccess, RegisterArray registers, int implicitMemoryBarriers, 81 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 the list 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 list is equal to 126 * its {@linkplain Register#number number}. 127 */ 128 public RegisterArray getRegisters() { 129 return registers; 130 } 131 132 /** 133 * Gets a list of all registers available for storing values on this architecture. This may be a 134 * subset of {@link #getRegisters()}, depending on the capabilities of this particular CPU. 135 */ 136 public RegisterArray 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 /** 160 * Gets the offset in bytes from the beginning of a call instruction to the displacement. 161 */ 162 public int getMachineCodeCallDisplacementOffset() { 163 return machineCodeCallDisplacementOffset; 164 } 165 166 /** 167 * Determines the barriers in a given barrier mask that are explicitly required on this 168 * architecture. 169 * 170 * @param barriers a mask of the barrier constants 171 * @return the value of {@code barriers} minus the barriers unnecessary on this architecture 172 */ 173 public final int requiredBarriers(int barriers) { 174 return barriers & ~implicitMemoryBarriers; 175 } 176 177 /** 178 * Determine whether a kind can be stored in a register of a given category. 179 * 180 * @param category the category of the register 181 * @param kind the kind that should be stored in the register 182 */ 183 public abstract boolean canStoreValue(RegisterCategory category, PlatformKind kind); 184 185 /** 186 * Return the largest kind that can be stored in a register of a given category. 187 * 188 * @param category the category of the register 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 * Gets the {@link PlatformKind} that is used to store values of a given {@link JavaKind}. 195 * 196 * @return {@code null} if there no deterministic {@link PlatformKind} for {@code javaKind} 197 */ 198 public abstract PlatformKind getPlatformKind(JavaKind javaKind); 199 200 @Override 201 public final boolean equals(Object obj) { 202 if (obj == this) { 203 return true; 204 } 205 if (obj instanceof Architecture) { 206 Architecture that = (Architecture) obj; 207 if (this.name.equals(that.name)) { 208 assert this.byteOrder.equals(that.byteOrder); 209 assert this.implicitMemoryBarriers == that.implicitMemoryBarriers; 210 assert this.machineCodeCallDisplacementOffset == that.machineCodeCallDisplacementOffset; 211 assert this.registers.equals(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 }