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 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 Architecture(String name, PlatformKind wordKind, ByteOrder byteOrder, boolean unalignedMemoryAccess, RegisterArray registers, int implicitMemoryBarriers, int nativeCallDisplacementOffset, int returnAddressSize)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 toString()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 */ getWordSize()107 public int getWordSize() { 108 return wordKind.getSizeInBytes(); 109 } 110 getWordKind()111 public PlatformKind getWordKind() { 112 return wordKind; 113 } 114 115 /** 116 * Gets the name of this architecture. 117 */ getName()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 */ getRegisters()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 */ getAvailableValueRegisters()136 public RegisterArray getAvailableValueRegisters() { 137 return getRegisters(); 138 } 139 getByteOrder()140 public ByteOrder getByteOrder() { 141 return byteOrder; 142 } 143 144 /** 145 * @return true if the architecture supports unaligned memory accesses. 146 */ supportsUnalignedMemoryAccess()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 */ getReturnAddressSize()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 */ getMachineCodeCallDisplacementOffset()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 */ requiredBarriers(int barriers)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 */ canStoreValue(RegisterCategory category, PlatformKind kind)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 */ getLargestStorableKind(RegisterCategory category)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 */ getPlatformKind(JavaKind javaKind)196 public abstract PlatformKind getPlatformKind(JavaKind javaKind); 197 198 @Override equals(Object obj)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 this.registers.equals(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 hashCode()220 public final int hashCode() { 221 return name.hashCode(); 222 } 223 } 224