001/* 002 * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. 008 * 009 * This code is distributed in the hope that it will be useful, but WITHOUT 010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 011 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 012 * version 2 for more details (a copy is included in the LICENSE file that 013 * accompanied this code). 014 * 015 * You should have received a copy of the GNU General Public License version 016 * 2 along with this work; if not, write to the Free Software Foundation, 017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 018 * 019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 020 * or visit www.oracle.com if you need additional information or have any 021 * questions. 022 */ 023package com.oracle.graal.hotspot.amd64; 024 025import static jdk.internal.jvmci.hotspot.InitTimer.*; 026 027import java.util.*; 028 029import jdk.internal.jvmci.amd64.*; 030import jdk.internal.jvmci.code.*; 031import jdk.internal.jvmci.hotspot.*; 032import jdk.internal.jvmci.meta.*; 033import jdk.internal.jvmci.runtime.*; 034import jdk.internal.jvmci.service.*; 035 036import com.oracle.graal.api.replacements.*; 037import com.oracle.graal.compiler.amd64.*; 038import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.Plugins; 039import com.oracle.graal.hotspot.*; 040import com.oracle.graal.hotspot.meta.*; 041import com.oracle.graal.hotspot.nodes.type.*; 042import com.oracle.graal.hotspot.word.*; 043import com.oracle.graal.phases.util.*; 044import com.oracle.graal.replacements.amd64.*; 045 046@ServiceProvider(HotSpotBackendFactory.class) 047public class AMD64HotSpotBackendFactory implements HotSpotBackendFactory { 048 049 @Override 050 public HotSpotBackend createBackend(HotSpotGraalRuntimeProvider runtime, JVMCIBackend jvmci, HotSpotBackend host) { 051 assert host == null; 052 053 HotSpotProviders providers; 054 HotSpotRegistersProvider registers; 055 HotSpotCodeCacheProvider codeCache = (HotSpotCodeCacheProvider) jvmci.getCodeCache(); 056 TargetDescription target = codeCache.getTarget(); 057 HotSpotConstantReflectionProvider constantReflection = new HotSpotGraalConstantReflectionProvider(runtime.getJVMCIRuntime()); 058 HotSpotHostForeignCallsProvider foreignCalls; 059 Value[] nativeABICallerSaveRegisters; 060 HotSpotMetaAccessProvider metaAccess = (HotSpotMetaAccessProvider) jvmci.getMetaAccess(); 061 HotSpotLoweringProvider lowerer; 062 HotSpotSnippetReflectionProvider snippetReflection; 063 HotSpotReplacementsImpl replacements; 064 HotSpotSuitesProvider suites; 065 HotSpotWordTypes wordTypes; 066 Plugins plugins; 067 try (InitTimer t = timer("create providers")) { 068 try (InitTimer rt = timer("create HotSpotRegisters provider")) { 069 registers = createRegisters(); 070 } 071 try (InitTimer rt = timer("create NativeABICallerSaveRegisters")) { 072 nativeABICallerSaveRegisters = createNativeABICallerSaveRegisters(runtime.getConfig(), codeCache.getRegisterConfig()); 073 } 074 try (InitTimer rt = timer("create ForeignCalls provider")) { 075 foreignCalls = createForeignCalls(runtime, metaAccess, codeCache, nativeABICallerSaveRegisters); 076 } 077 try (InitTimer rt = timer("create Lowerer provider")) { 078 lowerer = createLowerer(runtime, metaAccess, foreignCalls, registers, target); 079 } 080 HotSpotStampProvider stampProvider = new HotSpotStampProvider(target.wordKind); 081 Providers p = new Providers(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, null, stampProvider); 082 083 try (InitTimer rt = timer("create SnippetReflection provider")) { 084 snippetReflection = createSnippetReflection(runtime); 085 } 086 try (InitTimer rt = timer("create Replacements provider")) { 087 replacements = createReplacements(runtime, p, snippetReflection); 088 } 089 try (InitTimer rt = timer("create WordTypes")) { 090 wordTypes = new HotSpotWordTypes(metaAccess, target.wordKind, stampProvider.createHubStamp(false), MethodPointerStamp.method()); 091 } 092 try (InitTimer rt = timer("create GraphBuilderPhase plugins")) { 093 plugins = createGraphBuilderPlugins(runtime, target, constantReflection, foreignCalls, metaAccess, snippetReflection, replacements, wordTypes, stampProvider); 094 replacements.setGraphBuilderPlugins(plugins); 095 } 096 try (InitTimer rt = timer("create Suites provider")) { 097 suites = createSuites(runtime, plugins, codeCache, registers); 098 } 099 providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, suites, registers, snippetReflection, wordTypes, plugins); 100 } 101 try (InitTimer rt = timer("instantiate backend")) { 102 return createBackend(runtime, providers); 103 } 104 } 105 106 protected Plugins createGraphBuilderPlugins(HotSpotGraalRuntimeProvider runtime, TargetDescription target, HotSpotConstantReflectionProvider constantReflection, 107 HotSpotHostForeignCallsProvider foreignCalls, HotSpotMetaAccessProvider metaAccess, HotSpotSnippetReflectionProvider snippetReflection, HotSpotReplacementsImpl replacements, 108 HotSpotWordTypes wordTypes, HotSpotStampProvider stampProvider) { 109 Plugins plugins = HotSpotGraphBuilderPlugins.create(runtime.getConfig(), wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, stampProvider, replacements); 110 AMD64GraphBuilderPlugins.register(plugins, foreignCalls, (AMD64) target.arch); 111 return plugins; 112 } 113 114 protected AMD64HotSpotBackend createBackend(HotSpotGraalRuntimeProvider runtime, HotSpotProviders providers) { 115 return new AMD64HotSpotBackend(runtime, providers); 116 } 117 118 protected HotSpotRegistersProvider createRegisters() { 119 return new HotSpotRegisters(AMD64.r15, AMD64.r12, AMD64.rsp); 120 } 121 122 protected HotSpotReplacementsImpl createReplacements(HotSpotGraalRuntimeProvider runtime, Providers p, SnippetReflectionProvider snippetReflection) { 123 return new HotSpotReplacementsImpl(p, snippetReflection, runtime.getConfig(), p.getCodeCache().getTarget()); 124 } 125 126 protected AMD64HotSpotForeignCallsProvider createForeignCalls(HotSpotGraalRuntimeProvider runtime, HotSpotMetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache, 127 Value[] nativeABICallerSaveRegisters) { 128 return new AMD64HotSpotForeignCallsProvider(runtime, metaAccess, codeCache, nativeABICallerSaveRegisters); 129 } 130 131 protected HotSpotSuitesProvider createSuites(HotSpotGraalRuntimeProvider runtime, Plugins plugins, CodeCacheProvider codeCache, HotSpotRegistersProvider registers) { 132 return new HotSpotSuitesProvider(new AMD64SuitesProvider(plugins), runtime, new AMD64HotSpotAddressLowering(codeCache, runtime.getConfig().getOopEncoding().base, 133 registers.getHeapBaseRegister())); 134 } 135 136 protected HotSpotSnippetReflectionProvider createSnippetReflection(HotSpotGraalRuntimeProvider runtime) { 137 return new HotSpotSnippetReflectionProvider(runtime); 138 } 139 140 protected HotSpotLoweringProvider createLowerer(HotSpotGraalRuntimeProvider runtime, HotSpotMetaAccessProvider metaAccess, HotSpotForeignCallsProvider foreignCalls, 141 HotSpotRegistersProvider registers, TargetDescription target) { 142 return new AMD64HotSpotLoweringProvider(runtime, metaAccess, foreignCalls, registers, target); 143 } 144 145 protected Value[] createNativeABICallerSaveRegisters(HotSpotVMConfig config, RegisterConfig regConfig) { 146 List<Register> callerSave = new ArrayList<>(Arrays.asList(regConfig.getAllocatableRegisters())); 147 if (config.windowsOs) { 148 // http://msdn.microsoft.com/en-us/library/9z1stfyw.aspx 149 callerSave.remove(AMD64.rdi); 150 callerSave.remove(AMD64.rsi); 151 callerSave.remove(AMD64.rbx); 152 callerSave.remove(AMD64.rbp); 153 callerSave.remove(AMD64.rsp); 154 callerSave.remove(AMD64.r12); 155 callerSave.remove(AMD64.r13); 156 callerSave.remove(AMD64.r14); 157 callerSave.remove(AMD64.r15); 158 callerSave.remove(AMD64.xmm6); 159 callerSave.remove(AMD64.xmm7); 160 callerSave.remove(AMD64.xmm8); 161 callerSave.remove(AMD64.xmm9); 162 callerSave.remove(AMD64.xmm10); 163 callerSave.remove(AMD64.xmm11); 164 callerSave.remove(AMD64.xmm12); 165 callerSave.remove(AMD64.xmm13); 166 callerSave.remove(AMD64.xmm14); 167 callerSave.remove(AMD64.xmm15); 168 } else { 169 /* 170 * System V Application Binary Interface, AMD64 Architecture Processor Supplement 171 * 172 * Draft Version 0.96 173 * 174 * http://www.uclibc.org/docs/psABI-x86_64.pdf 175 * 176 * 3.2.1 177 * 178 * ... 179 * 180 * This subsection discusses usage of each register. Registers %rbp, %rbx and %r12 181 * through %r15 "belong" to the calling function and the called function is required to 182 * preserve their values. In other words, a called function must preserve these 183 * registers' values for its caller. Remaining registers "belong" to the called 184 * function. If a calling function wants to preserve such a register value across a 185 * function call, it must save the value in its local stack frame. 186 */ 187 callerSave.remove(AMD64.rbp); 188 callerSave.remove(AMD64.rbx); 189 callerSave.remove(AMD64.r12); 190 callerSave.remove(AMD64.r13); 191 callerSave.remove(AMD64.r14); 192 callerSave.remove(AMD64.r15); 193 } 194 Value[] nativeABICallerSaveRegisters = new Value[callerSave.size()]; 195 for (int i = 0; i < callerSave.size(); i++) { 196 nativeABICallerSaveRegisters[i] = callerSave.get(i).asValue(); 197 } 198 return nativeABICallerSaveRegisters; 199 } 200 201 public String getArchitecture() { 202 return "AMD64"; 203 } 204 205 public String getGraalRuntimeName() { 206 return "basic"; 207 } 208 209 @Override 210 public String toString() { 211 return getGraalRuntimeName() + ":" + getArchitecture(); 212 } 213}