/* * 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.aarch64; import static jdk.vm.ci.code.MemoryBarriers.*; import static jdk.vm.ci.code.Register.*; import java.nio.*; import java.util.*; import jdk.vm.ci.code.*; import jdk.vm.ci.code.Register.RegisterCategory; import jdk.vm.ci.meta.*; /** * Represents the AARCH64 architecture. */ public class AArch64 extends Architecture { public static final RegisterCategory CPU = new RegisterCategory("CPU"); // @formatter:off // General purpose CPU registers public static final Register r0 = new Register(0, 0, "r0", CPU); public static final Register r1 = new Register(0, 0, "r1", CPU); public static final Register r2 = new Register(0, 0, "r2", CPU); public static final Register r3 = new Register(0, 0, "r3", CPU); public static final Register r4 = new Register(0, 0, "r4", CPU); public static final Register r5 = new Register(0, 0, "r5", CPU); public static final Register r6 = new Register(0, 0, "r6", CPU); public static final Register r7 = new Register(0, 0, "r7", CPU); public static final Register r8 = new Register(0, 0, "r8", CPU); public static final Register r9 = new Register(0, 0, "r9", CPU); public static final Register r10 = new Register(0, 0, "r10", CPU); public static final Register r11 = new Register(0, 0, "r11", CPU); public static final Register r12 = new Register(0, 0, "r12", CPU); public static final Register r13 = new Register(0, 0, "r13", CPU); public static final Register r14 = new Register(0, 0, "r14", CPU); public static final Register r15 = new Register(0, 0, "r15", CPU); public static final Register r16 = new Register(0, 0, "r16", CPU); public static final Register r17 = new Register(0, 0, "r17", CPU); public static final Register r18 = new Register(0, 0, "r18", CPU); public static final Register r19 = new Register(0, 0, "r19", CPU); public static final Register r20 = new Register(0, 0, "r20", CPU); public static final Register r21 = new Register(0, 0, "r21", CPU); public static final Register r22 = new Register(0, 0, "r22", CPU); public static final Register r23 = new Register(0, 0, "r23", CPU); public static final Register r24 = new Register(0, 0, "r24", CPU); public static final Register r25 = new Register(0, 0, "r25", CPU); public static final Register r26 = new Register(0, 0, "r26", CPU); public static final Register r27 = new Register(0, 0, "r27", CPU); public static final Register rheapbase = new Register(0, 0, "rheapbase", CPU); public static final Register rthread = new Register(0, 0, "rthread", CPU); public static final Register fp = new Register(0, 0, "rfp", CPU); public static final Register lr = new Register(0, 0, "rlr", CPU); public static final Register sp = new Register(0, 0, "rsp", CPU); public static final Register[] cpuRegisters = { r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, rheapbase, rthread, fp, lr, sp, }; private static final int SIMD_REFERENCE_MAP_SHIFT = 2; public static final RegisterCategory SIMD = new RegisterCategory("SIMD", cpuRegisters.length, SIMD_REFERENCE_MAP_SHIFT); // Simd registers public static final Register v0 = new Register(0, 0, "v0", SIMD); public static final Register v1 = new Register(0, 0, "v1", SIMD); public static final Register v2 = new Register(0, 0, "v2", SIMD); public static final Register v3 = new Register(0, 0, "v3", SIMD); public static final Register v4 = new Register(0, 0, "v4", SIMD); public static final Register v5 = new Register(0, 0, "v5", SIMD); public static final Register v6 = new Register(0, 0, "v6", SIMD); public static final Register v7 = new Register(0, 0, "v7", SIMD); public static final Register v8 = new Register(0, 0, "v8", SIMD); public static final Register v9 = new Register(0, 0, "v9", SIMD); public static final Register v10 = new Register(0, 0, "v10", SIMD); public static final Register v11 = new Register(0, 0, "v11", SIMD); public static final Register v12 = new Register(0, 0, "v12", SIMD); public static final Register v13 = new Register(0, 0, "v13", SIMD); public static final Register v14 = new Register(0, 0, "v14", SIMD); public static final Register v15 = new Register(0, 0, "v15", SIMD); public static final Register v16 = new Register(0, 0, "v16", SIMD); public static final Register v17 = new Register(0, 0, "v17", SIMD); public static final Register v18 = new Register(0, 0, "v18", SIMD); public static final Register v19 = new Register(0, 0, "v19", SIMD); public static final Register v20 = new Register(0, 0, "v20", SIMD); public static final Register v21 = new Register(0, 0, "v21", SIMD); public static final Register v22 = new Register(0, 0, "v22", SIMD); public static final Register v23 = new Register(0, 0, "v23", SIMD); public static final Register v24 = new Register(0, 0, "v24", SIMD); public static final Register v25 = new Register(0, 0, "v25", SIMD); public static final Register v26 = new Register(0, 0, "v26", SIMD); public static final Register v27 = new Register(0, 0, "v27", SIMD); public static final Register v28 = new Register(0, 0, "v28", SIMD); public static final Register v29 = new Register(0, 0, "v29", SIMD); public static final Register v30 = new Register(0, 0, "v30", SIMD); public static final Register v31 = new Register(0, 0, "v31", SIMD); public static final Register[] simdRegisters = { v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31 }; public static final Register[] allRegisters = { r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, rheapbase, rthread, fp, lr, sp, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31 }; // @formatter:on /** * Basic set of CPU features mirroring what is returned from the cpuid instruction. See: * {@code VM_Version::cpuFeatureFlags}. */ public static enum CPUFeature { FP, ASIMD, EVTSTRM, AES, PMULL, SHA1, SHA2, CRC32, A53MAC, DMB_ATOMICS } private final EnumSet features; /** * Set of flags to control code emission. */ public static enum Flag { UseBarriersForVolatile, UseCRC32, UseNeon } private final EnumSet flags; public AArch64(EnumSet features, EnumSet flags) { super("aarch64", JavaKind.Long, ByteOrder.LITTLE_ENDIAN, /*unalignedMemoryAccess*/true, allRegisters, /*implicitMemoryBarriers*/0, /*nativeCallDisplacementOffset*/0, cpuRegisters.length + (simdRegisters.length << SIMD_REFERENCE_MAP_SHIFT), /*returnAddressSize*/0); this.features = features; this.flags = flags; assert features.contains(CPUFeature.FP) : "minimum config for aarch64"; } public EnumSet getFeatures() { return features; } public EnumSet getFlags() { return flags; } @Override public PlatformKind getPlatformKind(JavaKind javaKind) { if (javaKind.isObject()) { return getWordKind(); } else { return javaKind; } } @Override public boolean canStoreValue(RegisterCategory category, PlatformKind platformKind) { if (!(platformKind instanceof JavaKind)) { return false; } JavaKind kind = (JavaKind) platformKind; if (category.equals(CPU)) { switch (kind) { case Boolean: case Byte: case Char: case Short: case Int: case Long: return true; } } else if (category.equals(SIMD)) { switch (kind) { case Float: case Double: return true; } } return false; } @Override public PlatformKind getLargestStorableKind(RegisterCategory category) { if (category.equals(CPU)) { return JavaKind.Long; } else if (category.equals(SIMD)) { return JavaKind.Double; } else { return JavaKind.Illegal; } } }