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