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 jdk.internal.jvmci.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
036@ServiceProvider(HotSpotJVMCIBackendFactory.class)
037public class AMD64HotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFactory {
038
039    protected Architecture createArchitecture(HotSpotVMConfig config) {
040        return new AMD64(computeFeatures(config), computeFlags(config));
041    }
042
043    protected EnumSet<AMD64.CPUFeature> computeFeatures(HotSpotVMConfig config) {
044        // Configure the feature set using the HotSpot flag settings.
045        EnumSet<AMD64.CPUFeature> features = EnumSet.noneOf(AMD64.CPUFeature.class);
046        assert config.useSSE >= 2 : "minimum config for x64";
047        features.add(AMD64.CPUFeature.SSE);
048        features.add(AMD64.CPUFeature.SSE2);
049        if ((config.x86CPUFeatures & config.cpuSSE3) != 0) {
050            features.add(AMD64.CPUFeature.SSE3);
051        }
052        if ((config.x86CPUFeatures & config.cpuSSSE3) != 0) {
053            features.add(AMD64.CPUFeature.SSSE3);
054        }
055        if ((config.x86CPUFeatures & config.cpuSSE4A) != 0) {
056            features.add(AMD64.CPUFeature.SSE4a);
057        }
058        if ((config.x86CPUFeatures & config.cpuSSE41) != 0) {
059            features.add(AMD64.CPUFeature.SSE4_1);
060        }
061        if ((config.x86CPUFeatures & config.cpuSSE42) != 0) {
062            features.add(AMD64.CPUFeature.SSE4_2);
063        }
064        if ((config.x86CPUFeatures & config.cpuAVX) != 0) {
065            features.add(AMD64.CPUFeature.AVX);
066        }
067        if ((config.x86CPUFeatures & config.cpuAVX2) != 0) {
068            features.add(AMD64.CPUFeature.AVX2);
069        }
070        if ((config.x86CPUFeatures & config.cpuERMS) != 0) {
071            features.add(AMD64.CPUFeature.ERMS);
072        }
073        if ((config.x86CPUFeatures & config.cpuLZCNT) != 0) {
074            features.add(AMD64.CPUFeature.LZCNT);
075        }
076        if ((config.x86CPUFeatures & config.cpuPOPCNT) != 0) {
077            features.add(AMD64.CPUFeature.POPCNT);
078        }
079        if ((config.x86CPUFeatures & config.cpuAES) != 0) {
080            features.add(AMD64.CPUFeature.AES);
081        }
082        if ((config.x86CPUFeatures & config.cpu3DNOWPREFETCH) != 0) {
083            features.add(AMD64.CPUFeature.AMD_3DNOW_PREFETCH);
084        }
085        if ((config.x86CPUFeatures & config.cpuBMI1) != 0) {
086            features.add(AMD64.CPUFeature.BMI1);
087        }
088        return features;
089    }
090
091    protected EnumSet<AMD64.Flag> computeFlags(HotSpotVMConfig config) {
092        EnumSet<AMD64.Flag> flags = EnumSet.noneOf(AMD64.Flag.class);
093        if (config.useCountLeadingZerosInstruction) {
094            flags.add(AMD64.Flag.UseCountLeadingZerosInstruction);
095        }
096        if (config.useCountTrailingZerosInstruction) {
097            flags.add(AMD64.Flag.UseCountTrailingZerosInstruction);
098        }
099        return flags;
100    }
101
102    protected TargetDescription createTarget(HotSpotVMConfig config) {
103        final int stackFrameAlignment = 16;
104        final int implicitNullCheckLimit = 4096;
105        final boolean inlineObjects = true;
106        return new TargetDescription(createArchitecture(config), true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects);
107    }
108
109    protected HotSpotConstantReflectionProvider createConstantReflection(HotSpotJVMCIRuntimeProvider runtime) {
110        return new HotSpotConstantReflectionProvider(runtime);
111    }
112
113    protected RegisterConfig createRegisterConfig(HotSpotJVMCIRuntimeProvider runtime, TargetDescription target) {
114        return new AMD64HotSpotRegisterConfig(target.arch, runtime.getConfig());
115    }
116
117    protected HotSpotCodeCacheProvider createCodeCache(HotSpotJVMCIRuntimeProvider runtime, TargetDescription target, RegisterConfig regConfig) {
118        return new HotSpotCodeCacheProvider(runtime, runtime.getConfig(), target, regConfig);
119    }
120
121    protected HotSpotMetaAccessProvider createMetaAccess(HotSpotJVMCIRuntimeProvider runtime) {
122        return new HotSpotMetaAccessProvider(runtime);
123    }
124
125    public String getArchitecture() {
126        return "AMD64";
127    }
128
129    @Override
130    public String toString() {
131        return getJVMCIRuntimeName() + ":" + getArchitecture();
132    }
133
134    public JVMCIBackend createJVMCIBackend(HotSpotJVMCIRuntimeProvider runtime, JVMCIBackend host) {
135
136        assert host == null;
137        TargetDescription target = createTarget(runtime.getConfig());
138
139        RegisterConfig regConfig;
140        HotSpotCodeCacheProvider codeCache;
141        ConstantReflectionProvider constantReflection;
142        HotSpotMetaAccessProvider metaAccess;
143        try (InitTimer t = timer("create providers")) {
144            try (InitTimer rt = timer("create MetaAccess provider")) {
145                metaAccess = createMetaAccess(runtime);
146            }
147            try (InitTimer rt = timer("create RegisterConfig")) {
148                regConfig = createRegisterConfig(runtime, target);
149            }
150            try (InitTimer rt = timer("create CodeCache provider")) {
151                codeCache = createCodeCache(runtime, target, regConfig);
152            }
153            try (InitTimer rt = timer("create ConstantReflection provider")) {
154                constantReflection = createConstantReflection(runtime);
155            }
156        }
157        try (InitTimer rt = timer("instantiate backend")) {
158            return createBackend(metaAccess, codeCache, constantReflection);
159        }
160    }
161
162    protected JVMCIBackend createBackend(HotSpotMetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache, ConstantReflectionProvider constantReflection) {
163        return new JVMCIBackend(metaAccess, codeCache, constantReflection);
164    }
165
166    public String getJVMCIRuntimeName() {
167        return "basic";
168    }
169}