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.aarch64; 24 25 import static jdk.vm.ci.code.MemoryBarriers.*; 26 import static jdk.vm.ci.code.Register.*; 27 28 import java.nio.*; 29 import java.util.*; 30 31 import jdk.vm.ci.code.*; 32 import jdk.vm.ci.code.Register.RegisterCategory; 33 import jdk.vm.ci.meta.*; 34 35 /** 36 * Represents the AARCH64 architecture. 37 */ 38 public class AArch64 extends Architecture { 39 40 public static final RegisterCategory CPU = new RegisterCategory("CPU"); 41 42 // @formatter:off 43 44 // General purpose CPU registers 45 public static final Register r0 = new Register(0, 0, "r0", CPU); 46 public static final Register r1 = new Register(0, 0, "r1", CPU); 47 public static final Register r2 = new Register(0, 0, "r2", CPU); 48 public static final Register r3 = new Register(0, 0, "r3", CPU); 49 public static final Register r4 = new Register(0, 0, "r4", CPU); 50 public static final Register r5 = new Register(0, 0, "r5", CPU); 51 public static final Register r6 = new Register(0, 0, "r6", CPU); 52 public static final Register r7 = new Register(0, 0, "r7", CPU); 53 public static final Register r8 = new Register(0, 0, "r8", CPU); 54 public static final Register r9 = new Register(0, 0, "r9", CPU); 55 public static final Register r10 = new Register(0, 0, "r10", CPU); 56 public static final Register r11 = new Register(0, 0, "r11", CPU); 57 public static final Register r12 = new Register(0, 0, "r12", CPU); 58 public static final Register r13 = new Register(0, 0, "r13", CPU); 59 public static final Register r14 = new Register(0, 0, "r14", CPU); 60 public static final Register r15 = new Register(0, 0, "r15", CPU); 61 public static final Register r16 = new Register(0, 0, "r16", CPU); 62 public static final Register r17 = new Register(0, 0, "r17", CPU); 63 public static final Register r18 = new Register(0, 0, "r18", CPU); 64 public static final Register r19 = new Register(0, 0, "r19", CPU); 65 public static final Register r20 = new Register(0, 0, "r20", CPU); 66 public static final Register r21 = new Register(0, 0, "r21", CPU); 67 public static final Register r22 = new Register(0, 0, "r22", CPU); 68 public static final Register r23 = new Register(0, 0, "r23", CPU); 69 public static final Register r24 = new Register(0, 0, "r24", CPU); 70 public static final Register r25 = new Register(0, 0, "r25", CPU); 71 public static final Register r26 = new Register(0, 0, "r26", CPU); 72 public static final Register r27 = new Register(0, 0, "r27", CPU); 73 public static final Register rheapbase = new Register(0, 0, "rheapbase", CPU); 74 public static final Register rthread = new Register(0, 0, "rthread", CPU); 75 public static final Register fp = new Register(0, 0, "rfp", CPU); 76 public static final Register lr = new Register(0, 0, "rlr", CPU); 77 public static final Register sp = new Register(0, 0, "rsp", CPU); 78 79 public static final Register[] cpuRegisters = { 80 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, 81 r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, 82 r20, r21, r22, r23, r24, r25, r26, r27, 83 rheapbase, rthread, fp, lr, sp, 84 }; 85 86 private static final int SIMD_REFERENCE_MAP_SHIFT = 2; 87 88 public static final RegisterCategory SIMD = new RegisterCategory("SIMD", cpuRegisters.length, SIMD_REFERENCE_MAP_SHIFT); 89 90 // Simd registers 91 public static final Register v0 = new Register(0, 0, "v0", SIMD); 92 public static final Register v1 = new Register(0, 0, "v1", SIMD); 93 public static final Register v2 = new Register(0, 0, "v2", SIMD); 94 public static final Register v3 = new Register(0, 0, "v3", SIMD); 95 public static final Register v4 = new Register(0, 0, "v4", SIMD); 96 public static final Register v5 = new Register(0, 0, "v5", SIMD); 97 public static final Register v6 = new Register(0, 0, "v6", SIMD); 98 public static final Register v7 = new Register(0, 0, "v7", SIMD); 99 public static final Register v8 = new Register(0, 0, "v8", SIMD); 100 public static final Register v9 = new Register(0, 0, "v9", SIMD); 101 public static final Register v10 = new Register(0, 0, "v10", SIMD); 102 public static final Register v11 = new Register(0, 0, "v11", SIMD); 103 public static final Register v12 = new Register(0, 0, "v12", SIMD); 104 public static final Register v13 = new Register(0, 0, "v13", SIMD); 105 public static final Register v14 = new Register(0, 0, "v14", SIMD); 106 public static final Register v15 = new Register(0, 0, "v15", SIMD); 107 public static final Register v16 = new Register(0, 0, "v16", SIMD); 108 public static final Register v17 = new Register(0, 0, "v17", SIMD); 109 public static final Register v18 = new Register(0, 0, "v18", SIMD); 110 public static final Register v19 = new Register(0, 0, "v19", SIMD); 111 public static final Register v20 = new Register(0, 0, "v20", SIMD); 112 public static final Register v21 = new Register(0, 0, "v21", SIMD); 113 public static final Register v22 = new Register(0, 0, "v22", SIMD); 114 public static final Register v23 = new Register(0, 0, "v23", SIMD); 115 public static final Register v24 = new Register(0, 0, "v24", SIMD); 116 public static final Register v25 = new Register(0, 0, "v25", SIMD); 117 public static final Register v26 = new Register(0, 0, "v26", SIMD); 118 public static final Register v27 = new Register(0, 0, "v27", SIMD); 119 public static final Register v28 = new Register(0, 0, "v28", SIMD); 120 public static final Register v29 = new Register(0, 0, "v29", SIMD); 121 public static final Register v30 = new Register(0, 0, "v30", SIMD); 122 public static final Register v31 = new Register(0, 0, "v31", SIMD); 123 124 public static final Register[] simdRegisters = { 125 v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, 126 v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, 127 v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, 128 v30, v31 129 }; 130 131 public static final Register[] allRegisters = { 132 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, 133 r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, 134 r20, r21, r22, r23, r24, r25, r26, r27, 135 rheapbase, rthread, fp, lr, sp, 136 137 v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, 138 v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, 139 v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, 140 v30, v31 141 }; 142 143 // @formatter:on 144 145 /** 146 * Basic set of CPU features mirroring what is returned from the cpuid instruction. See: 147 * {@code VM_Version::cpuFeatureFlags}. 148 */ 149 public static enum CPUFeature { 150 FP, 151 ASIMD, 152 EVTSTRM, 153 AES, 154 PMULL, 155 SHA1, 156 SHA2, 157 CRC32, 158 A53MAC, 159 DMB_ATOMICS 160 } 161 162 private final EnumSet<CPUFeature> features; 163 164 /** 165 * Set of flags to control code emission. 166 */ 167 public static enum Flag { 168 UseBarriersForVolatile, 169 UseCRC32, 170 UseNeon 171 } 172 173 private final EnumSet<Flag> flags; 174 175 public AArch64(EnumSet<CPUFeature> features, EnumSet<Flag> flags) { 176 super("aarch64", JavaKind.Long, ByteOrder.LITTLE_ENDIAN, 177 /*unalignedMemoryAccess*/true, allRegisters, 178 /*implicitMemoryBarriers*/0, /*nativeCallDisplacementOffset*/0, 179 cpuRegisters.length + (simdRegisters.length << SIMD_REFERENCE_MAP_SHIFT), 180 /*returnAddressSize*/0); 181 this.features = features; 182 this.flags = flags; 183 assert features.contains(CPUFeature.FP) : "minimum config for aarch64"; 184 } 185 186 public EnumSet<CPUFeature> getFeatures() { 187 return features; 188 } 189 190 public EnumSet<Flag> getFlags() { 191 return flags; 192 } 193 194 @Override 195 public PlatformKind getPlatformKind(JavaKind javaKind) { 196 if (javaKind.isObject()) { 197 return getWordKind(); 198 } else { 199 return javaKind; 200 } 201 } 202 203 @Override 204 public boolean canStoreValue(RegisterCategory category, PlatformKind platformKind) { 205 if (!(platformKind instanceof JavaKind)) { 206 return false; 207 } 208 209 JavaKind kind = (JavaKind) platformKind; 210 if (category.equals(CPU)) { 211 switch (kind) { 212 case Boolean: 213 case Byte: 214 case Char: 215 case Short: 216 case Int: 217 case Long: 218 return true; 219 } 220 } else if (category.equals(SIMD)) { 221 switch (kind) { 222 case Float: 223 case Double: 224 return true; 225 } 226 } 227 228 return false; 229 } 230 231 @Override 232 public PlatformKind getLargestStorableKind(RegisterCategory category) { 233 if (category.equals(CPU)) { 234 return JavaKind.Long; 235 } else if (category.equals(SIMD)) { 236 return JavaKind.Double; 237 } else { 238 return JavaKind.Illegal; 239 } 240 } 241 }