1 /* 2 * Copyright (c) 2009, 2021, 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.amd64; 24 25 import static jdk.vm.ci.code.MemoryBarriers.LOAD_LOAD; 26 import static jdk.vm.ci.code.MemoryBarriers.LOAD_STORE; 27 import static jdk.vm.ci.code.MemoryBarriers.STORE_STORE; 28 import static jdk.vm.ci.code.Register.SPECIAL; 29 30 import java.nio.ByteOrder; 31 import java.util.EnumSet; 32 33 import jdk.vm.ci.code.Architecture; 34 import jdk.vm.ci.code.CPUFeatureName; 35 import jdk.vm.ci.code.Register; 36 import jdk.vm.ci.code.Register.RegisterCategory; 37 import jdk.vm.ci.code.RegisterArray; 38 import jdk.vm.ci.meta.JavaKind; 39 import jdk.vm.ci.meta.PlatformKind; 40 41 /** 42 * Represents the AMD64 architecture. 43 */ 44 public class AMD64 extends Architecture { 45 46 public static final RegisterCategory CPU = new RegisterCategory("CPU"); 47 48 // @formatter:off 49 50 // General purpose CPU registers 51 public static final Register rax = new Register(0, 0, "rax", CPU); 52 public static final Register rcx = new Register(1, 1, "rcx", CPU); 53 public static final Register rdx = new Register(2, 2, "rdx", CPU); 54 public static final Register rbx = new Register(3, 3, "rbx", CPU); 55 public static final Register rsp = new Register(4, 4, "rsp", CPU); 56 public static final Register rbp = new Register(5, 5, "rbp", CPU); 57 public static final Register rsi = new Register(6, 6, "rsi", CPU); 58 public static final Register rdi = new Register(7, 7, "rdi", CPU); 59 60 public static final Register r8 = new Register(8, 8, "r8", CPU); 61 public static final Register r9 = new Register(9, 9, "r9", CPU); 62 public static final Register r10 = new Register(10, 10, "r10", CPU); 63 public static final Register r11 = new Register(11, 11, "r11", CPU); 64 public static final Register r12 = new Register(12, 12, "r12", CPU); 65 public static final Register r13 = new Register(13, 13, "r13", CPU); 66 public static final Register r14 = new Register(14, 14, "r14", CPU); 67 public static final Register r15 = new Register(15, 15, "r15", CPU); 68 69 public static final Register[] cpuRegisters = { 70 rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi, 71 r8, r9, r10, r11, r12, r13, r14, r15 72 }; 73 74 public static final RegisterCategory XMM = new RegisterCategory("XMM"); 75 76 // XMM registers 77 public static final Register xmm0 = new Register(16, 0, "xmm0", XMM); 78 public static final Register xmm1 = new Register(17, 1, "xmm1", XMM); 79 public static final Register xmm2 = new Register(18, 2, "xmm2", XMM); 80 public static final Register xmm3 = new Register(19, 3, "xmm3", XMM); 81 public static final Register xmm4 = new Register(20, 4, "xmm4", XMM); 82 public static final Register xmm5 = new Register(21, 5, "xmm5", XMM); 83 public static final Register xmm6 = new Register(22, 6, "xmm6", XMM); 84 public static final Register xmm7 = new Register(23, 7, "xmm7", XMM); 85 86 public static final Register xmm8 = new Register(24, 8, "xmm8", XMM); 87 public static final Register xmm9 = new Register(25, 9, "xmm9", XMM); 88 public static final Register xmm10 = new Register(26, 10, "xmm10", XMM); 89 public static final Register xmm11 = new Register(27, 11, "xmm11", XMM); 90 public static final Register xmm12 = new Register(28, 12, "xmm12", XMM); 91 public static final Register xmm13 = new Register(29, 13, "xmm13", XMM); 92 public static final Register xmm14 = new Register(30, 14, "xmm14", XMM); 93 public static final Register xmm15 = new Register(31, 15, "xmm15", XMM); 94 95 public static final Register xmm16 = new Register(32, 16, "xmm16", XMM); 96 public static final Register xmm17 = new Register(33, 17, "xmm17", XMM); 97 public static final Register xmm18 = new Register(34, 18, "xmm18", XMM); 98 public static final Register xmm19 = new Register(35, 19, "xmm19", XMM); 99 public static final Register xmm20 = new Register(36, 20, "xmm20", XMM); 100 public static final Register xmm21 = new Register(37, 21, "xmm21", XMM); 101 public static final Register xmm22 = new Register(38, 22, "xmm22", XMM); 102 public static final Register xmm23 = new Register(39, 23, "xmm23", XMM); 103 104 public static final Register xmm24 = new Register(40, 24, "xmm24", XMM); 105 public static final Register xmm25 = new Register(41, 25, "xmm25", XMM); 106 public static final Register xmm26 = new Register(42, 26, "xmm26", XMM); 107 public static final Register xmm27 = new Register(43, 27, "xmm27", XMM); 108 public static final Register xmm28 = new Register(44, 28, "xmm28", XMM); 109 public static final Register xmm29 = new Register(45, 29, "xmm29", XMM); 110 public static final Register xmm30 = new Register(46, 30, "xmm30", XMM); 111 public static final Register xmm31 = new Register(47, 31, "xmm31", XMM); 112 113 public static final Register[] xmmRegistersSSE = { 114 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, 115 xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 116 }; 117 118 public static final Register[] xmmRegistersAVX512 = { 119 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, 120 xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15, 121 xmm16, xmm17, xmm18, xmm19, xmm20, xmm21, xmm22, xmm23, 122 xmm24, xmm25, xmm26, xmm27, xmm28, xmm29, xmm30, xmm31 123 }; 124 125 public static final RegisterCategory MASK = new RegisterCategory("MASK", false); 126 127 public static final Register k0 = new Register(48, 0, "k0", MASK); 128 public static final Register k1 = new Register(49, 1, "k1", MASK); 129 public static final Register k2 = new Register(50, 2, "k2", MASK); 130 public static final Register k3 = new Register(51, 3, "k3", MASK); 131 public static final Register k4 = new Register(52, 4, "k4", MASK); 132 public static final Register k5 = new Register(53, 5, "k5", MASK); 133 public static final Register k6 = new Register(54, 6, "k6", MASK); 134 public static final Register k7 = new Register(55, 7, "k7", MASK); 135 136 public static final RegisterArray valueRegistersSSE = new RegisterArray( 137 rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi, 138 r8, r9, r10, r11, r12, r13, r14, r15, 139 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, 140 xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 141 ); 142 143 public static final RegisterArray valueRegistersAVX512 = new RegisterArray( 144 rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi, 145 r8, r9, r10, r11, r12, r13, r14, r15, 146 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, 147 xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15, 148 xmm16, xmm17, xmm18, xmm19, xmm20, xmm21, xmm22, xmm23, 149 xmm24, xmm25, xmm26, xmm27, xmm28, xmm29, xmm30, xmm31, 150 k0, k1, k2, k3, k4, k5, k6, k7 151 ); 152 153 /** 154 * Register used to construct an instruction-relative address. 155 */ 156 public static final Register rip = new Register(56, -1, "rip", SPECIAL); 157 158 public static final RegisterArray allRegisters = new RegisterArray( 159 rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi, 160 r8, r9, r10, r11, r12, r13, r14, r15, 161 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, 162 xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15, 163 xmm16, xmm17, xmm18, xmm19, xmm20, xmm21, xmm22, xmm23, 164 xmm24, xmm25, xmm26, xmm27, xmm28, xmm29, xmm30, xmm31, 165 k0, k1, k2, k3, k4, k5, k6, k7, 166 rip 167 ); 168 169 // @formatter:on 170 171 /** 172 * Basic set of CPU features mirroring what is returned from the cpuid instruction. See: 173 * {@code VM_Version::cpuFeatureFlags}. 174 */ 175 public enum CPUFeature implements CPUFeatureName { 176 CX8, 177 CMOV, 178 FXSR, 179 HT, 180 MMX, 181 AMD_3DNOW_PREFETCH, 182 SSE, 183 SSE2, 184 SSE3, 185 SSSE3, 186 SSE4A, 187 SSE4_1, 188 SSE4_2, 189 POPCNT, 190 LZCNT, 191 TSC, 192 TSCINV, 193 TSCINV_BIT, 194 AVX, 195 AVX2, 196 AES, 197 ERMS, 198 CLMUL, 199 BMI1, 200 BMI2, 201 RTM, 202 ADX, 203 AVX512F, 204 AVX512DQ, 205 AVX512PF, 206 AVX512ER, 207 AVX512CD, 208 AVX512BW, 209 AVX512VL, 210 SHA, 211 FMA, 212 VZEROUPPER, 213 AVX512_VPOPCNTDQ, 214 AVX512_VPCLMULQDQ, 215 AVX512_VAES, 216 AVX512_VNNI, 217 FLUSH, 218 FLUSHOPT, 219 CLWB, 220 AVX512_VBMI2, 221 AVX512_VBMI, 222 HV, 223 SERIALIZE, 224 GFNI, 225 AVX512_BITALG, 226 } 227 228 private final EnumSet<CPUFeature> features; 229 230 /** 231 * Set of flags to control code emission. 232 */ 233 public enum Flag { 234 UseCountLeadingZerosInstruction, 235 UseCountTrailingZerosInstruction 236 } 237 238 private final EnumSet<Flag> flags; 239 240 private final AMD64Kind largestKind; 241 242 public AMD64(EnumSet<CPUFeature> features, EnumSet<Flag> flags) { 243 super("AMD64", AMD64Kind.QWORD, ByteOrder.LITTLE_ENDIAN, true, allRegisters, LOAD_LOAD | LOAD_STORE | STORE_STORE, 1, 8); 244 this.features = features; 245 this.flags = flags; 246 assert features.contains(CPUFeature.SSE2) : "minimum config for x64"; 247 248 if (features.contains(CPUFeature.AVX512F)) { 249 largestKind = AMD64Kind.V512_QWORD; 250 } else if (features.contains(CPUFeature.AVX)) { 251 largestKind = AMD64Kind.V256_QWORD; 252 } else { 253 largestKind = AMD64Kind.V128_QWORD; 254 } 255 } 256 257 @Override 258 public EnumSet<CPUFeature> getFeatures() { 259 return features; 260 } 261 262 public EnumSet<Flag> getFlags() { 263 return flags; 264 } 265 266 @Override 267 public RegisterArray getAvailableValueRegisters() { 268 if (features.contains(CPUFeature.AVX512F)) { 269 return valueRegistersAVX512; 270 } else { 271 return valueRegistersSSE; 272 } 273 } 274 275 @Override 276 public PlatformKind getPlatformKind(JavaKind javaKind) { 277 switch (javaKind) { 278 case Boolean: 279 case Byte: 280 return AMD64Kind.BYTE; 281 case Short: 282 case Char: 283 return AMD64Kind.WORD; 284 case Int: 285 return AMD64Kind.DWORD; 286 case Long: 287 case Object: 288 return AMD64Kind.QWORD; 289 case Float: 290 return AMD64Kind.SINGLE; 291 case Double: 292 return AMD64Kind.DOUBLE; 293 default: 294 return null; 295 } 296 } 297 298 @Override 299 public boolean canStoreValue(RegisterCategory category, PlatformKind platformKind) { 300 AMD64Kind kind = (AMD64Kind) platformKind; 301 if (kind.isInteger()) { 302 return category.equals(CPU); 303 } else if (kind.isXMM()) { 304 return category.equals(XMM); 305 } else { 306 assert kind.isMask(); 307 return category.equals(MASK); 308 } 309 } 310 311 @Override 312 public AMD64Kind getLargestStorableKind(RegisterCategory category) { 313 if (category.equals(CPU)) { 314 return AMD64Kind.QWORD; 315 } else if (category.equals(XMM)) { 316 return largestKind; 317 } else if (category.equals(MASK)) { 318 return AMD64Kind.MASK64; 319 } else { 320 return null; 321 } 322 } 323 } --- EOF ---