001/* 002 * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. 008 * 009 * This code is distributed in the hope that it will be useful, but WITHOUT 010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 011 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 012 * version 2 for more details (a copy is included in the LICENSE file that 013 * accompanied this code). 014 * 015 * You should have received a copy of the GNU General Public License version 016 * 2 along with this work; if not, write to the Free Software Foundation, 017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 018 * 019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 020 * or visit www.oracle.com if you need additional information or have any 021 * questions. 022 */ 023package jdk.internal.jvmci.code; 024 025import java.nio.*; 026import java.util.*; 027 028import jdk.internal.jvmci.code.Register.*; 029import jdk.internal.jvmci.meta.*; 030 031/** 032 * Represents a CPU architecture, including information such as its endianness, CPU registers, word 033 * width, etc. 034 */ 035public abstract class Architecture { 036 037 /** 038 * The number of entries required in a {@link ReferenceMap} covering all the registers that may 039 * store references. The index of a register in the reference map is given by 040 * {@link Register#getReferenceMapIndex()}. 041 */ 042 private final int registerReferenceMapSize; 043 044 /** 045 * Represents the natural size of words (typically registers and pointers) of this architecture, 046 * in bytes. 047 */ 048 private final int wordSize; 049 050 /** 051 * The name of this architecture (e.g. "AMD64", "SPARCv9"). 052 */ 053 private final String name; 054 055 /** 056 * Array of all available registers on this architecture. The index of each register in this 057 * array is equal to its {@linkplain Register#number number}. 058 */ 059 private final Register[] registers; 060 061 /** 062 * The byte ordering can be either little or big endian. 063 */ 064 private final ByteOrder byteOrder; 065 066 /** 067 * Whether the architecture supports unaligned memory accesses. 068 */ 069 private final boolean unalignedMemoryAccess; 070 071 /** 072 * Mask of the barrier constants denoting the barriers that are not required to be explicitly 073 * inserted under this architecture. 074 */ 075 private final int implicitMemoryBarriers; 076 077 /** 078 * Offset in bytes from the beginning of a call instruction to the displacement. 079 */ 080 private final int machineCodeCallDisplacementOffset; 081 082 /** 083 * The size of the return address pushed to the stack by a call instruction. A value of 0 084 * denotes that call linkage uses registers instead (e.g. SPARC). 085 */ 086 private final int returnAddressSize; 087 088 protected Architecture(String name, int wordSize, ByteOrder byteOrder, boolean unalignedMemoryAccess, Register[] registers, int implicitMemoryBarriers, int nativeCallDisplacementOffset, 089 int registerReferenceMapSize, int returnAddressSize) { 090 this.name = name; 091 this.registers = registers; 092 this.wordSize = wordSize; 093 this.byteOrder = byteOrder; 094 this.unalignedMemoryAccess = unalignedMemoryAccess; 095 this.implicitMemoryBarriers = implicitMemoryBarriers; 096 this.machineCodeCallDisplacementOffset = nativeCallDisplacementOffset; 097 this.registerReferenceMapSize = registerReferenceMapSize; 098 this.returnAddressSize = returnAddressSize; 099 } 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 wordSize; 121 } 122 123 /** 124 * Gets the name of this architecture. 125 */ 126 public String getName() { 127 return name; 128 } 129 130 /** 131 * Gets an array of all available registers on this architecture. The index of each register in 132 * this array is equal to its {@linkplain Register#number number}. 133 */ 134 public Register[] getRegisters() { 135 return registers.clone(); 136 } 137 138 public ByteOrder getByteOrder() { 139 return byteOrder; 140 } 141 142 /** 143 * @return true if the architecture supports unaligned memory accesses. 144 */ 145 public boolean supportsUnalignedMemoryAccess() { 146 return unalignedMemoryAccess; 147 } 148 149 /** 150 * Gets the size of the return address pushed to the stack by a call instruction. A value of 0 151 * denotes that call linkage uses registers instead. 152 */ 153 public int getReturnAddressSize() { 154 return returnAddressSize; 155 } 156 157 /** 158 * Gets the offset in bytes from the beginning of a call instruction to the displacement. 159 */ 160 public int getMachineCodeCallDisplacementOffset() { 161 return machineCodeCallDisplacementOffset; 162 } 163 164 /** 165 * Determines the barriers in a given barrier mask that are explicitly required on this 166 * architecture. 167 * 168 * @param barriers a mask of the barrier constants 169 * @return the value of {@code barriers} minus the barriers unnecessary on this architecture 170 */ 171 public final int requiredBarriers(int barriers) { 172 return barriers & ~implicitMemoryBarriers; 173 } 174 175 /** 176 * Gets the size in bytes of the specified kind for this target. 177 * 178 * @param kind the kind for which to get the size 179 * 180 * @return the size in bytes of {@code kind} 181 */ 182 public int getSizeInBytes(PlatformKind kind) { 183 switch ((Kind) kind) { 184 case Boolean: 185 return 1; 186 case Byte: 187 return 1; 188 case Char: 189 return 2; 190 case Short: 191 return 2; 192 case Int: 193 return 4; 194 case Long: 195 return 8; 196 case Float: 197 return 4; 198 case Double: 199 return 8; 200 case Object: 201 return wordSize; 202 default: 203 return 0; 204 } 205 } 206 207 /** 208 * Determine whether a kind can be stored in a register of a given category. 209 * 210 * @param category the category of the register 211 * @param kind the kind that should be stored in the register 212 */ 213 public abstract boolean canStoreValue(RegisterCategory category, PlatformKind kind); 214 215 /** 216 * Return the largest kind that can be stored in a register of a given category. 217 * 218 * @param category the category of the register 219 * @return the largest kind that can be stored in a register {@code category} 220 */ 221 public abstract PlatformKind getLargestStorableKind(RegisterCategory category); 222 223 @Override 224 public final boolean equals(Object obj) { 225 if (obj == this) { 226 return true; 227 } 228 if (obj instanceof Architecture) { 229 Architecture that = (Architecture) obj; 230 if (this.name.equals(that.name)) { 231 assert this.byteOrder.equals(that.byteOrder); 232 assert this.implicitMemoryBarriers == that.implicitMemoryBarriers; 233 assert this.machineCodeCallDisplacementOffset == that.machineCodeCallDisplacementOffset; 234 assert this.registerReferenceMapSize == that.registerReferenceMapSize; 235 assert Arrays.equals(this.registers, that.registers); 236 assert this.returnAddressSize == that.returnAddressSize; 237 assert this.unalignedMemoryAccess == that.unalignedMemoryAccess; 238 assert this.wordSize == that.wordSize; 239 return true; 240 } 241 } 242 return false; 243 } 244 245 @Override 246 public final int hashCode() { 247 return name.hashCode(); 248 } 249}