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.amd64; 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 AMD64 architecture. 37 */ 38 public class AMD64 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 rax = new Register(0, 0, "rax", CPU); 46 public static final Register rcx = new Register(1, 1, "rcx", CPU); 47 public static final Register rdx = new Register(2, 2, "rdx", CPU); 48 public static final Register rbx = new Register(3, 3, "rbx", CPU); 49 public static final Register rsp = new Register(4, 4, "rsp", CPU); 50 public static final Register rbp = new Register(5, 5, "rbp", CPU); 51 public static final Register rsi = new Register(6, 6, "rsi", CPU); 52 public static final Register rdi = new Register(7, 7, "rdi", CPU); 53 54 public static final Register r8 = new Register(8, 8, "r8", CPU); 55 public static final Register r9 = new Register(9, 9, "r9", CPU); 56 public static final Register r10 = new Register(10, 10, "r10", CPU); 57 public static final Register r11 = new Register(11, 11, "r11", CPU); 58 public static final Register r12 = new Register(12, 12, "r12", CPU); 59 public static final Register r13 = new Register(13, 13, "r13", CPU); 60 public static final Register r14 = new Register(14, 14, "r14", CPU); 61 public static final Register r15 = new Register(15, 15, "r15", CPU); 62 63 public static final Register[] cpuRegisters = { 64 rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi, 65 r8, r9, r10, r11, r12, r13, r14, r15 66 }; 67 68 private static final int XMM_REFERENCE_MAP_SHIFT = 2; 69 70 public static final RegisterCategory XMM = new RegisterCategory("XMM", cpuRegisters.length, XMM_REFERENCE_MAP_SHIFT); 71 72 // XMM registers 73 public static final Register xmm0 = new Register(16, 0, "xmm0", XMM); 74 public static final Register xmm1 = new Register(17, 1, "xmm1", XMM); 75 public static final Register xmm2 = new Register(18, 2, "xmm2", XMM); 76 public static final Register xmm3 = new Register(19, 3, "xmm3", XMM); 77 public static final Register xmm4 = new Register(20, 4, "xmm4", XMM); 78 public static final Register xmm5 = new Register(21, 5, "xmm5", XMM); 79 public static final Register xmm6 = new Register(22, 6, "xmm6", XMM); 80 public static final Register xmm7 = new Register(23, 7, "xmm7", XMM); 81 82 public static final Register xmm8 = new Register(24, 8, "xmm8", XMM); 83 public static final Register xmm9 = new Register(25, 9, "xmm9", XMM); 84 public static final Register xmm10 = new Register(26, 10, "xmm10", XMM); 85 public static final Register xmm11 = new Register(27, 11, "xmm11", XMM); 86 public static final Register xmm12 = new Register(28, 12, "xmm12", XMM); 87 public static final Register xmm13 = new Register(29, 13, "xmm13", XMM); 88 public static final Register xmm14 = new Register(30, 14, "xmm14", XMM); 89 public static final Register xmm15 = new Register(31, 15, "xmm15", XMM); 90 91 public static final Register[] xmmRegisters = { 92 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, 93 xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 94 }; 95 96 public static final Register[] cpuxmmRegisters = { 97 rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi, 98 r8, r9, r10, r11, r12, r13, r14, r15, 99 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, 100 xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 101 }; 102 103 /** 104 * Register used to construct an instruction-relative address. 105 */ 106 public static final Register rip = new Register(32, -1, "rip", SPECIAL); 107 108 public static final Register[] allRegisters = { 109 rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi, 110 r8, r9, r10, r11, r12, r13, r14, r15, 111 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, 112 xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15, 113 rip 114 }; 115 116 // @formatter:on 117 118 /** 119 * Basic set of CPU features mirroring what is returned from the cpuid instruction. See: 120 * {@code VM_Version::cpuFeatureFlags}. 121 */ 122 public static enum CPUFeature { 123 CX8, 124 CMOV, 125 FXSR, 126 HT, 127 MMX, 128 AMD_3DNOW_PREFETCH, 129 SSE, 130 SSE2, 131 SSE3, 132 SSSE3, 133 SSE4A, 134 SSE4_1, 135 SSE4_2, 136 POPCNT, 137 LZCNT, 138 TSC, 139 TSCINV, 140 AVX, 141 AVX2, 142 AES, 143 ERMS, 144 CLMUL, 145 BMI1, 146 BMI2, 147 RTM, 148 ADX, 149 AVX512F, 150 AVX512DQ, 151 AVX512PF, 152 AVX512ER, 153 AVX512CD, 154 AVX512BW 155 } 156 157 private final EnumSet<CPUFeature> features; 158 159 /** 160 * Set of flags to control code emission. 161 */ 162 public static enum Flag { 163 UseCountLeadingZerosInstruction, 164 UseCountTrailingZerosInstruction 165 } 166 167 private final EnumSet<Flag> flags; 168 169 public AMD64(EnumSet<CPUFeature> features, EnumSet<Flag> flags) { 170 super("AMD64", JavaKind.Long, ByteOrder.LITTLE_ENDIAN, true, allRegisters, LOAD_STORE | STORE_STORE, 1, cpuRegisters.length + (xmmRegisters.length << XMM_REFERENCE_MAP_SHIFT), 8); 171 this.features = features; 172 this.flags = flags; 173 assert features.contains(CPUFeature.SSE2) : "minimum config for x64"; 174 } 175 176 public EnumSet<CPUFeature> getFeatures() { 177 return features; 178 } 179 180 public EnumSet<Flag> getFlags() { 181 return flags; 182 } 183 184 @Override 185 public PlatformKind getPlatformKind(JavaKind javaKind) { 186 if (javaKind.isObject()) { 187 return getWordKind(); 188 } else { 189 return javaKind; 190 } 191 } 192 193 @Override 194 public boolean canStoreValue(RegisterCategory category, PlatformKind platformKind) { 195 if (!(platformKind instanceof JavaKind)) { 196 return false; 197 } 198 199 JavaKind kind = (JavaKind) platformKind; 200 if (category.equals(CPU)) { 201 switch (kind) { 202 case Boolean: 203 case Byte: 204 case Char: 205 case Short: 206 case Int: 207 case Long: 208 return true; 209 } 210 } else if (category.equals(XMM)) { 211 switch (kind) { 212 case Float: 213 case Double: 214 return true; 215 } 216 } 217 218 return false; 219 } 220 221 @Override 222 public PlatformKind getLargestStorableKind(RegisterCategory category) { 223 if (category.equals(CPU)) { 224 return JavaKind.Long; 225 } else if (category.equals(XMM)) { 226 return JavaKind.Double; 227 } else { 228 return JavaKind.Illegal; 229 } 230 } 231 }