1 /* 2 * Copyright (c) 2012, 2020, 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 24 25 package org.graalvm.compiler.hotspot.amd64; 26 27 import static jdk.vm.ci.common.InitTimer.timer; 28 29 import java.util.ArrayList; 30 import java.util.List; 31 32 import org.graalvm.compiler.bytecode.BytecodeProvider; 33 import org.graalvm.compiler.core.common.spi.ConstantFieldProvider; 34 import org.graalvm.compiler.core.common.spi.MetaAccessExtensionProvider; 35 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; 36 import org.graalvm.compiler.hotspot.HotSpotBackend; 37 import org.graalvm.compiler.hotspot.HotSpotBackendFactory; 38 import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider; 39 import org.graalvm.compiler.hotspot.HotSpotReplacementsImpl; 40 import org.graalvm.compiler.hotspot.meta.AddressLoweringHotSpotSuitesProvider; 41 import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProvider; 42 import org.graalvm.compiler.hotspot.meta.HotSpotGraalConstantFieldProvider; 43 import org.graalvm.compiler.hotspot.meta.HotSpotGraphBuilderPlugins; 44 import org.graalvm.compiler.hotspot.meta.HotSpotHostForeignCallsProvider; 45 import org.graalvm.compiler.hotspot.meta.HotSpotLoweringProvider; 46 import org.graalvm.compiler.hotspot.meta.HotSpotMetaAccessExtensionProvider; 47 import org.graalvm.compiler.hotspot.meta.HotSpotPlatformConfigurationProvider; 48 import org.graalvm.compiler.hotspot.meta.HotSpotProviders; 49 import org.graalvm.compiler.hotspot.meta.HotSpotRegisters; 50 import org.graalvm.compiler.hotspot.meta.HotSpotRegistersProvider; 51 import org.graalvm.compiler.hotspot.meta.HotSpotSnippetReflectionProvider; 52 import org.graalvm.compiler.hotspot.meta.HotSpotStampProvider; 53 import org.graalvm.compiler.hotspot.meta.HotSpotSuitesProvider; 54 import org.graalvm.compiler.hotspot.word.HotSpotWordTypes; 55 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins; 56 import org.graalvm.compiler.nodes.spi.PlatformConfigurationProvider; 57 import org.graalvm.compiler.nodes.spi.Replacements; 58 import org.graalvm.compiler.options.OptionValues; 59 import org.graalvm.compiler.phases.common.AddressLoweringPhase; 60 import org.graalvm.compiler.phases.tiers.CompilerConfiguration; 61 import org.graalvm.compiler.phases.util.Providers; 62 import org.graalvm.compiler.replacements.amd64.AMD64GraphBuilderPlugins; 63 import org.graalvm.compiler.serviceprovider.JavaVersionUtil; 64 import org.graalvm.compiler.serviceprovider.ServiceProvider; 65 import org.graalvm.compiler.word.WordTypes; 66 67 import jdk.vm.ci.amd64.AMD64; 68 import jdk.vm.ci.code.Architecture; 69 import jdk.vm.ci.code.Register; 70 import jdk.vm.ci.code.RegisterConfig; 71 import jdk.vm.ci.code.TargetDescription; 72 import jdk.vm.ci.common.InitTimer; 73 import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider; 74 import jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider; 75 import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; 76 import jdk.vm.ci.hotspot.HotSpotMetaAccessProvider; 77 import jdk.vm.ci.meta.Value; 78 import jdk.vm.ci.runtime.JVMCIBackend; 79 80 @ServiceProvider(HotSpotBackendFactory.class) 81 public class AMD64HotSpotBackendFactory extends HotSpotBackendFactory { 82 83 @Override getName()84 public String getName() { 85 return "community"; 86 } 87 88 @Override getArchitecture()89 public Class<? extends Architecture> getArchitecture() { 90 return AMD64.class; 91 } 92 93 @Override 94 @SuppressWarnings("try") createBackend(HotSpotGraalRuntimeProvider graalRuntime, CompilerConfiguration compilerConfiguration, HotSpotJVMCIRuntime jvmciRuntime, HotSpotBackend host)95 public HotSpotBackend createBackend(HotSpotGraalRuntimeProvider graalRuntime, CompilerConfiguration compilerConfiguration, HotSpotJVMCIRuntime jvmciRuntime, HotSpotBackend host) { 96 assert host == null; 97 98 OptionValues options = graalRuntime.getOptions(); 99 JVMCIBackend jvmci = jvmciRuntime.getHostJVMCIBackend(); 100 GraalHotSpotVMConfig config = graalRuntime.getVMConfig(); 101 HotSpotProviders providers; 102 HotSpotRegistersProvider registers; 103 HotSpotCodeCacheProvider codeCache = (HotSpotCodeCacheProvider) jvmci.getCodeCache(); 104 TargetDescription target = codeCache.getTarget(); 105 HotSpotHostForeignCallsProvider foreignCalls; 106 Value[] nativeABICallerSaveRegisters; 107 HotSpotMetaAccessProvider metaAccess = (HotSpotMetaAccessProvider) jvmci.getMetaAccess(); 108 HotSpotConstantReflectionProvider constantReflection = (HotSpotConstantReflectionProvider) jvmci.getConstantReflection(); 109 ConstantFieldProvider constantFieldProvider = new HotSpotGraalConstantFieldProvider(config, metaAccess); 110 HotSpotLoweringProvider lowerer; 111 HotSpotStampProvider stampProvider; 112 HotSpotPlatformConfigurationProvider platformConfigurationProvider; 113 HotSpotMetaAccessExtensionProvider metaAccessExtensionProvider; 114 HotSpotSnippetReflectionProvider snippetReflection; 115 HotSpotReplacementsImpl replacements; 116 HotSpotSuitesProvider suites; 117 HotSpotWordTypes wordTypes; 118 Plugins plugins; 119 BytecodeProvider bytecodeProvider; 120 try (InitTimer t = timer("create providers")) { 121 try (InitTimer rt = timer("create HotSpotRegisters provider")) { 122 registers = createRegisters(); 123 } 124 try (InitTimer rt = timer("create NativeABICallerSaveRegisters")) { 125 nativeABICallerSaveRegisters = createNativeABICallerSaveRegisters(config, codeCache.getRegisterConfig()); 126 } 127 try (InitTimer rt = timer("create WordTypes")) { 128 wordTypes = createWordTypes(metaAccess, target); 129 } 130 try (InitTimer rt = timer("create ForeignCalls provider")) { 131 foreignCalls = createForeignCalls(jvmciRuntime, graalRuntime, metaAccess, codeCache, wordTypes, nativeABICallerSaveRegisters); 132 } 133 try (InitTimer rt = timer("create platform configuration provider")) { 134 platformConfigurationProvider = createConfigInfoProvider(config, metaAccess); 135 } 136 try (InitTimer rt = timer("create MetaAccessExtensionProvider")) { 137 metaAccessExtensionProvider = createMetaAccessExtensionProvider(); 138 } 139 try (InitTimer rt = timer("create stamp provider")) { 140 stampProvider = createStampProvider(); 141 } 142 try (InitTimer rt = timer("create Lowerer provider")) { 143 lowerer = createLowerer(graalRuntime, metaAccess, foreignCalls, registers, constantReflection, platformConfigurationProvider, metaAccessExtensionProvider, target); 144 } 145 146 Providers p = new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, null, stampProvider, platformConfigurationProvider, 147 metaAccessExtensionProvider); 148 149 try (InitTimer rt = timer("create SnippetReflection provider")) { 150 snippetReflection = createSnippetReflection(graalRuntime, constantReflection, wordTypes); 151 } 152 try (InitTimer rt = timer("create Bytecode provider")) { 153 bytecodeProvider = createBytecodeProvider(metaAccess, snippetReflection); 154 } 155 try (InitTimer rt = timer("create Replacements provider")) { 156 replacements = createReplacements(target, p, snippetReflection, bytecodeProvider); 157 } 158 try (InitTimer rt = timer("create GraphBuilderPhase plugins")) { 159 plugins = createGraphBuilderPlugins(graalRuntime, compilerConfiguration, config, target, constantReflection, foreignCalls, metaAccess, snippetReflection, replacements, wordTypes, 160 options); 161 replacements.setGraphBuilderPlugins(plugins); 162 } 163 try (InitTimer rt = timer("create Suites provider")) { 164 suites = createSuites(config, graalRuntime, compilerConfiguration, plugins, registers, replacements, options); 165 } 166 providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, suites, registers, 167 snippetReflection, wordTypes, plugins, platformConfigurationProvider, metaAccessExtensionProvider); 168 replacements.setProviders(providers); 169 replacements.maybeInitializeEncoder(options); 170 } 171 try (InitTimer rt = timer("instantiate backend")) { 172 return createBackend(config, graalRuntime, providers); 173 } 174 } 175 createGraphBuilderPlugins(HotSpotGraalRuntimeProvider graalRuntime, CompilerConfiguration compilerConfiguration, GraalHotSpotVMConfig config, TargetDescription target, HotSpotConstantReflectionProvider constantReflection, HotSpotHostForeignCallsProvider foreignCalls, HotSpotMetaAccessProvider metaAccess, HotSpotSnippetReflectionProvider snippetReflection, HotSpotReplacementsImpl replacements, HotSpotWordTypes wordTypes, OptionValues options)176 protected Plugins createGraphBuilderPlugins(HotSpotGraalRuntimeProvider graalRuntime, 177 CompilerConfiguration compilerConfiguration, 178 GraalHotSpotVMConfig config, 179 TargetDescription target, 180 HotSpotConstantReflectionProvider constantReflection, 181 HotSpotHostForeignCallsProvider foreignCalls, 182 HotSpotMetaAccessProvider metaAccess, 183 HotSpotSnippetReflectionProvider snippetReflection, 184 HotSpotReplacementsImpl replacements, 185 HotSpotWordTypes wordTypes, 186 OptionValues options) { 187 Plugins plugins = HotSpotGraphBuilderPlugins.create( 188 graalRuntime, 189 compilerConfiguration, 190 config, 191 wordTypes, 192 metaAccess, 193 constantReflection, 194 snippetReflection, 195 foreignCalls, 196 replacements, 197 options, 198 target); 199 AMD64GraphBuilderPlugins.register(plugins, replacements, (AMD64) target.arch, false, JavaVersionUtil.JAVA_SPEC >= 9, config.useFMAIntrinsics); 200 return plugins; 201 } 202 createBackend(GraalHotSpotVMConfig config, HotSpotGraalRuntimeProvider runtime, HotSpotProviders providers)203 protected AMD64HotSpotBackend createBackend(GraalHotSpotVMConfig config, HotSpotGraalRuntimeProvider runtime, HotSpotProviders providers) { 204 return new AMD64HotSpotBackend(config, runtime, providers); 205 } 206 createRegisters()207 protected HotSpotRegistersProvider createRegisters() { 208 return new HotSpotRegisters(AMD64.r15, AMD64.r12, AMD64.rsp); 209 } 210 createForeignCalls(HotSpotJVMCIRuntime jvmciRuntime, HotSpotGraalRuntimeProvider runtime, HotSpotMetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache, WordTypes wordTypes, Value[] nativeABICallerSaveRegisters)211 protected AMD64HotSpotForeignCallsProvider createForeignCalls(HotSpotJVMCIRuntime jvmciRuntime, HotSpotGraalRuntimeProvider runtime, HotSpotMetaAccessProvider metaAccess, 212 HotSpotCodeCacheProvider codeCache, WordTypes wordTypes, Value[] nativeABICallerSaveRegisters) { 213 return new AMD64HotSpotForeignCallsProvider(jvmciRuntime, runtime, metaAccess, codeCache, wordTypes, nativeABICallerSaveRegisters); 214 } 215 216 /** 217 * @param replacements 218 */ createSuites(GraalHotSpotVMConfig config, HotSpotGraalRuntimeProvider runtime, CompilerConfiguration compilerConfiguration, Plugins plugins, HotSpotRegistersProvider registers, Replacements replacements, OptionValues options)219 protected HotSpotSuitesProvider createSuites(GraalHotSpotVMConfig config, HotSpotGraalRuntimeProvider runtime, CompilerConfiguration compilerConfiguration, Plugins plugins, 220 HotSpotRegistersProvider registers, Replacements replacements, OptionValues options) { 221 return new AddressLoweringHotSpotSuitesProvider(new AMD64HotSpotSuitesCreator(compilerConfiguration, plugins), config, runtime, 222 new AddressLoweringPhase(new AMD64HotSpotAddressLowering(config, registers.getHeapBaseRegister(), options))); 223 } 224 createLowerer(HotSpotGraalRuntimeProvider runtime, HotSpotMetaAccessProvider metaAccess, HotSpotForeignCallsProvider foreignCalls, HotSpotRegistersProvider registers, HotSpotConstantReflectionProvider constantReflection, PlatformConfigurationProvider platformConfig, MetaAccessExtensionProvider metaAccessExtensionProvider, TargetDescription target)225 protected HotSpotLoweringProvider createLowerer(HotSpotGraalRuntimeProvider runtime, HotSpotMetaAccessProvider metaAccess, HotSpotForeignCallsProvider foreignCalls, 226 HotSpotRegistersProvider registers, HotSpotConstantReflectionProvider constantReflection, PlatformConfigurationProvider platformConfig, 227 MetaAccessExtensionProvider metaAccessExtensionProvider, 228 TargetDescription target) { 229 return new AMD64HotSpotLoweringProvider(runtime, metaAccess, foreignCalls, registers, constantReflection, platformConfig, metaAccessExtensionProvider, target); 230 } 231 createNativeABICallerSaveRegisters(GraalHotSpotVMConfig config, RegisterConfig regConfig)232 protected Value[] createNativeABICallerSaveRegisters(GraalHotSpotVMConfig config, RegisterConfig regConfig) { 233 List<Register> callerSave = new ArrayList<>(regConfig.getAllocatableRegisters().asList()); 234 if (config.osName.equals("windows")) { 235 // http://msdn.microsoft.com/en-us/library/9z1stfyw.aspx 236 callerSave.remove(AMD64.rdi); 237 callerSave.remove(AMD64.rsi); 238 callerSave.remove(AMD64.rbx); 239 callerSave.remove(AMD64.rbp); 240 callerSave.remove(AMD64.rsp); 241 callerSave.remove(AMD64.r12); 242 callerSave.remove(AMD64.r13); 243 callerSave.remove(AMD64.r14); 244 callerSave.remove(AMD64.r15); 245 callerSave.remove(AMD64.xmm6); 246 callerSave.remove(AMD64.xmm7); 247 callerSave.remove(AMD64.xmm8); 248 callerSave.remove(AMD64.xmm9); 249 callerSave.remove(AMD64.xmm10); 250 callerSave.remove(AMD64.xmm11); 251 callerSave.remove(AMD64.xmm12); 252 callerSave.remove(AMD64.xmm13); 253 callerSave.remove(AMD64.xmm14); 254 callerSave.remove(AMD64.xmm15); 255 } else { 256 /* 257 * System V Application Binary Interface, AMD64 Architecture Processor Supplement 258 * 259 * Draft Version 0.96 260 * 261 * http://www.uclibc.org/docs/psABI-x86_64.pdf 262 * 263 * 3.2.1 264 * 265 * ... 266 * 267 * This subsection discusses usage of each register. Registers %rbp, %rbx and %r12 268 * through %r15 "belong" to the calling function and the called function is required to 269 * preserve their values. In other words, a called function must preserve these 270 * registers' values for its caller. Remaining registers "belong" to the called 271 * function. If a calling function wants to preserve such a register value across a 272 * function call, it must save the value in its local stack frame. 273 */ 274 callerSave.remove(AMD64.rbp); 275 callerSave.remove(AMD64.rbx); 276 callerSave.remove(AMD64.r12); 277 callerSave.remove(AMD64.r13); 278 callerSave.remove(AMD64.r14); 279 callerSave.remove(AMD64.r15); 280 } 281 Value[] nativeABICallerSaveRegisters = new Value[callerSave.size()]; 282 for (int i = 0; i < callerSave.size(); i++) { 283 nativeABICallerSaveRegisters[i] = callerSave.get(i).asValue(); 284 } 285 return nativeABICallerSaveRegisters; 286 } 287 288 @Override toString()289 public String toString() { 290 return "AMD64"; 291 } 292 } 293