/*
 * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package jdk.vm.ci.code;

import java.nio.ByteOrder;

import jdk.vm.ci.code.Register.RegisterCategory;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.PlatformKind;

Represents a CPU architecture, including information such as its endianness, CPU registers, word width, etc.
/** * Represents a CPU architecture, including information such as its endianness, CPU registers, word * width, etc. */
public abstract class Architecture {
The architecture specific type of a native word.
/** * The architecture specific type of a native word. */
private final PlatformKind wordKind;
The name of this architecture (e.g. "AMD64", "SPARCv9").
/** * The name of this architecture (e.g. "AMD64", "SPARCv9"). */
private final String name;
List of all available registers on this architecture. The index of each register in this list is equal to its number.
/** * List of all available registers on this architecture. The index of each register in this list * is equal to its {@linkplain Register#number number}. */
private final RegisterArray registers;
The byte ordering can be either little or big endian.
/** * The byte ordering can be either little or big endian. */
private final ByteOrder byteOrder;
Whether the architecture supports unaligned memory accesses.
/** * Whether the architecture supports unaligned memory accesses. */
private final boolean unalignedMemoryAccess;
Mask of the barrier constants denoting the barriers that are not required to be explicitly inserted under this architecture.
/** * Mask of the barrier constants denoting the barriers that are not required to be explicitly * inserted under this architecture. */
private final int implicitMemoryBarriers;
Offset in bytes from the beginning of a call instruction to the displacement.
/** * Offset in bytes from the beginning of a call instruction to the displacement. */
private final int machineCodeCallDisplacementOffset;
The size of the return address pushed to the stack by a call instruction. A value of 0 denotes that call linkage uses registers instead (e.g. SPARC).
/** * The size of the return address pushed to the stack by a call instruction. A value of 0 * denotes that call linkage uses registers instead (e.g. SPARC). */
private final int returnAddressSize; protected Architecture(String name, PlatformKind wordKind, ByteOrder byteOrder, boolean unalignedMemoryAccess, RegisterArray registers, int implicitMemoryBarriers, int nativeCallDisplacementOffset, int returnAddressSize) { this.name = name; this.registers = registers; this.wordKind = wordKind; this.byteOrder = byteOrder; this.unalignedMemoryAccess = unalignedMemoryAccess; this.implicitMemoryBarriers = implicitMemoryBarriers; this.machineCodeCallDisplacementOffset = nativeCallDisplacementOffset; this.returnAddressSize = returnAddressSize; }
Converts this architecture to a string.
Returns:the string representation of this architecture
/** * Converts this architecture to a string. * * @return the string representation of this architecture */
@Override public final String toString() { return getName().toLowerCase(); }
Gets the natural size of words (typically registers and pointers) of this architecture, in bytes.
/** * Gets the natural size of words (typically registers and pointers) of this architecture, in * bytes. */
public int getWordSize() { return wordKind.getSizeInBytes(); } public PlatformKind getWordKind() { return wordKind; }
Gets the name of this architecture.
/** * Gets the name of this architecture. */
public String getName() { return name; }
Gets the list of all registers that exist on this architecture. This contains all registers that exist in the specification of this architecture. Not all of them may be available on this particular architecture instance. The index of each register in this list is equal to its number.
/** * Gets the list of all registers that exist on this architecture. This contains all registers * that exist in the specification of this architecture. Not all of them may be available on * this particular architecture instance. The index of each register in this list is equal to * its {@linkplain Register#number number}. */
public RegisterArray getRegisters() { return registers; }
Gets a list of all registers available for storing values on this architecture. This may be a subset of getRegisters(), depending on the capabilities of this particular CPU.
/** * Gets a list of all registers available for storing values on this architecture. This may be a * subset of {@link #getRegisters()}, depending on the capabilities of this particular CPU. */
public RegisterArray getAvailableValueRegisters() { return getRegisters(); } public ByteOrder getByteOrder() { return byteOrder; }
Returns:true if the architecture supports unaligned memory accesses.
/** * @return true if the architecture supports unaligned memory accesses. */
public boolean supportsUnalignedMemoryAccess() { return unalignedMemoryAccess; }
Gets the size of the return address pushed to the stack by a call instruction. A value of 0 denotes that call linkage uses registers instead.
/** * Gets the size of the return address pushed to the stack by a call instruction. A value of 0 * denotes that call linkage uses registers instead. */
public int getReturnAddressSize() { return returnAddressSize; }
Gets the offset in bytes from the beginning of a call instruction to the displacement.
/** * Gets the offset in bytes from the beginning of a call instruction to the displacement. */
public int getMachineCodeCallDisplacementOffset() { return machineCodeCallDisplacementOffset; }
Determines the barriers in a given barrier mask that are explicitly required on this architecture.
Params:
  • barriers – a mask of the barrier constants
Returns:the value of barriers minus the barriers unnecessary on this architecture
/** * Determines the barriers in a given barrier mask that are explicitly required on this * architecture. * * @param barriers a mask of the barrier constants * @return the value of {@code barriers} minus the barriers unnecessary on this architecture */
public final int requiredBarriers(int barriers) { return barriers & ~implicitMemoryBarriers; }
Determine whether a kind can be stored in a register of a given category.
Params:
  • category – the category of the register
  • kind – the kind that should be stored in the register
/** * Determine whether a kind can be stored in a register of a given category. * * @param category the category of the register * @param kind the kind that should be stored in the register */
public abstract boolean canStoreValue(RegisterCategory category, PlatformKind kind);
Return the largest kind that can be stored in a register of a given category.
Params:
  • category – the category of the register
Returns:the largest kind that can be stored in a register category
/** * Return the largest kind that can be stored in a register of a given category. * * @param category the category of the register * @return the largest kind that can be stored in a register {@code category} */
public abstract PlatformKind getLargestStorableKind(RegisterCategory category);
Return the PlatformKind that is used to store values of a given JavaKind.
/** * Return the {@link PlatformKind} that is used to store values of a given {@link JavaKind}. */
public abstract PlatformKind getPlatformKind(JavaKind javaKind); @Override public final boolean equals(Object obj) { if (obj == this) { return true; } if (obj instanceof Architecture) { Architecture that = (Architecture) obj; if (this.name.equals(that.name)) { assert this.byteOrder.equals(that.byteOrder); assert this.implicitMemoryBarriers == that.implicitMemoryBarriers; assert this.machineCodeCallDisplacementOffset == that.machineCodeCallDisplacementOffset; assert this.registers.equals(that.registers); assert this.returnAddressSize == that.returnAddressSize; assert this.unalignedMemoryAccess == that.unalignedMemoryAccess; assert this.wordKind == that.wordKind; return true; } } return false; } @Override public final int hashCode() { return name.hashCode(); } }