# HG changeset patch # User Doug Simon # Date 1433280567 -7200 # Node ID e0b5d4fcd929eb9abeee3980eaba08aefc6e0330 # Parent 5024c80224c774655b804ce969b8da37a0a624cc moved HotSpotTargetDescription and [AMD64|SPARC]HotSpotRegisterConfig into JVMCI namespace (JBS:GRAAL-53) diff -r 5024c80224c7 -r e0b5d4fcd929 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DeoptimizationStub.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DeoptimizationStub.java Tue Jun 02 22:11:52 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DeoptimizationStub.java Tue Jun 02 23:29:27 2015 +0200 @@ -32,6 +32,7 @@ import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.stubs.*; import com.oracle.jvmci.hotspot.*; +import com.oracle.jvmci.hotspot.amd64.*; final class AMD64DeoptimizationStub extends DeoptimizationStub { diff -r 5024c80224c7 -r e0b5d4fcd929 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java Tue Jun 02 22:11:52 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,272 +0,0 @@ -/* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.hotspot.amd64; - -import com.oracle.jvmci.amd64.*; -import com.oracle.jvmci.code.Register; -import com.oracle.jvmci.code.RegisterConfig; -import com.oracle.jvmci.code.TargetDescription; -import com.oracle.jvmci.code.CallingConvention; -import com.oracle.jvmci.code.StackSlot; -import com.oracle.jvmci.code.RegisterAttributes; -import com.oracle.jvmci.code.CalleeSaveLayout; -import com.oracle.jvmci.code.Architecture; -import com.oracle.jvmci.meta.JavaType; -import com.oracle.jvmci.meta.Value; -import com.oracle.jvmci.meta.PlatformKind; -import com.oracle.jvmci.meta.AllocatableValue; -import com.oracle.jvmci.meta.Kind; - -import static com.oracle.graal.compiler.common.GraalOptions.*; -import static com.oracle.jvmci.amd64.AMD64.*; - -import java.util.*; - -import com.oracle.jvmci.code.CallingConvention.Type; -import com.oracle.graal.compiler.common.*; -import com.oracle.jvmci.common.*; -import com.oracle.jvmci.hotspot.*; - -public class AMD64HotSpotRegisterConfig implements RegisterConfig { - - private final Architecture architecture; - - private final Register[] allocatable; - - private final int maxFrameSize; - - /** - * The same as {@link #allocatable}, except if parameter registers are removed with the - * {@link GraalOptions#RegisterPressure} option. The caller saved registers always include all - * parameter registers. - */ - private final Register[] callerSaved; - - private final boolean allAllocatableAreCallerSaved; - - private final RegisterAttributes[] attributesMap; - - public int getMaximumFrameSize() { - return maxFrameSize; - } - - @Override - public Register[] getAllocatableRegisters() { - return allocatable.clone(); - } - - public Register[] filterAllocatableRegisters(PlatformKind kind, Register[] registers) { - ArrayList list = new ArrayList<>(); - for (Register reg : registers) { - if (architecture.canStoreValue(reg.getRegisterCategory(), kind)) { - list.add(reg); - } - } - - Register[] ret = list.toArray(new Register[list.size()]); - return ret; - } - - @Override - public RegisterAttributes[] getAttributesMap() { - return attributesMap.clone(); - } - - private final Register[] javaGeneralParameterRegisters; - private final Register[] nativeGeneralParameterRegisters; - private final Register[] xmmParameterRegisters = {xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7}; - - /* - * Some ABIs (e.g. Windows) require a so-called "home space", that is a save area on the stack - * to store the argument registers - */ - private final boolean needsNativeStackHomeSpace; - - private final CalleeSaveLayout csl; - - private static Register[] initAllocatable(boolean reserveForHeapBase) { - Register[] registers = null; - // @formatter:off - if (reserveForHeapBase) { - registers = new Register[] { - rax, rbx, rcx, rdx, /*rsp,*/ rbp, rsi, rdi, r8, r9, r10, r11, /*r12,*/ r13, r14, /*r15, */ - xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, - xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 - }; - } else { - registers = new Register[] { - rax, rbx, rcx, rdx, /*rsp,*/ rbp, rsi, rdi, r8, r9, r10, r11, r12, r13, r14, /*r15, */ - xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, - xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 - }; - } - // @formatter:on - return registers; - } - - public AMD64HotSpotRegisterConfig(Architecture architecture, HotSpotVMConfig config) { - this(architecture, config, initAllocatable(config.useCompressedOops)); - assert callerSaved.length == allocatable.length || RegisterPressure.getValue() != null; - } - - public AMD64HotSpotRegisterConfig(Architecture architecture, HotSpotVMConfig config, Register[] allocatable) { - this.architecture = architecture; - this.maxFrameSize = config.maxFrameSize; - - if (config.windowsOs) { - javaGeneralParameterRegisters = new Register[]{rdx, r8, r9, rdi, rsi, rcx}; - nativeGeneralParameterRegisters = new Register[]{rcx, rdx, r8, r9}; - this.needsNativeStackHomeSpace = true; - } else { - javaGeneralParameterRegisters = new Register[]{rsi, rdx, rcx, r8, r9, rdi}; - nativeGeneralParameterRegisters = new Register[]{rdi, rsi, rdx, rcx, r8, r9}; - this.needsNativeStackHomeSpace = false; - } - - csl = null; - this.allocatable = allocatable.clone(); - Set callerSaveSet = new HashSet<>(); - Collections.addAll(callerSaveSet, allocatable); - Collections.addAll(callerSaveSet, xmmParameterRegisters); - Collections.addAll(callerSaveSet, javaGeneralParameterRegisters); - Collections.addAll(callerSaveSet, nativeGeneralParameterRegisters); - callerSaved = callerSaveSet.toArray(new Register[callerSaveSet.size()]); - - allAllocatableAreCallerSaved = true; - attributesMap = RegisterAttributes.createMap(this, AMD64.allRegisters); - } - - @Override - public Register[] getCallerSaveRegisters() { - return callerSaved; - } - - @Override - public boolean areAllAllocatableRegistersCallerSaved() { - return allAllocatableAreCallerSaved; - } - - @Override - public Register getRegisterForRole(int index) { - throw new UnsupportedOperationException(); - } - - @Override - public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, TargetDescription target, boolean stackOnly) { - if (type == Type.NativeCall) { - return callingConvention(nativeGeneralParameterRegisters, returnType, parameterTypes, type, target, stackOnly); - } - // On x64, parameter locations are the same whether viewed - // from the caller or callee perspective - return callingConvention(javaGeneralParameterRegisters, returnType, parameterTypes, type, target, stackOnly); - } - - public Register[] getCallingConventionRegisters(Type type, Kind kind) { - if (architecture.canStoreValue(XMM, kind)) { - return xmmParameterRegisters; - } - assert architecture.canStoreValue(CPU, kind); - return type == Type.NativeCall ? nativeGeneralParameterRegisters : javaGeneralParameterRegisters; - } - - private CallingConvention callingConvention(Register[] generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, Type type, TargetDescription target, boolean stackOnly) { - AllocatableValue[] locations = new AllocatableValue[parameterTypes.length]; - - int currentGeneral = 0; - int currentXMM = 0; - int currentStackOffset = type == Type.NativeCall && needsNativeStackHomeSpace ? generalParameterRegisters.length * target.wordSize : 0; - - for (int i = 0; i < parameterTypes.length; i++) { - final Kind kind = parameterTypes[i].getKind(); - - switch (kind) { - case Byte: - case Boolean: - case Short: - case Char: - case Int: - case Long: - case Object: - if (!stackOnly && currentGeneral < generalParameterRegisters.length) { - Register register = generalParameterRegisters[currentGeneral++]; - locations[i] = register.asValue(target.getLIRKind(kind)); - } - break; - case Float: - case Double: - if (!stackOnly && currentXMM < xmmParameterRegisters.length) { - Register register = xmmParameterRegisters[currentXMM++]; - locations[i] = register.asValue(target.getLIRKind(kind)); - } - break; - default: - throw JVMCIError.shouldNotReachHere(); - } - - if (locations[i] == null) { - locations[i] = StackSlot.get(target.getLIRKind(kind.getStackKind()), currentStackOffset, !type.out); - currentStackOffset += Math.max(target.getSizeInBytes(kind), target.wordSize); - } - } - - Kind returnKind = returnType == null ? Kind.Void : returnType.getKind(); - AllocatableValue returnLocation = returnKind == Kind.Void ? Value.ILLEGAL : getReturnRegister(returnKind).asValue(target.getLIRKind(returnKind.getStackKind())); - return new CallingConvention(currentStackOffset, returnLocation, locations); - } - - @Override - public Register getReturnRegister(Kind kind) { - switch (kind) { - case Boolean: - case Byte: - case Char: - case Short: - case Int: - case Long: - case Object: - return rax; - case Float: - case Double: - return xmm0; - case Void: - case Illegal: - return null; - default: - throw new UnsupportedOperationException("no return register for type " + kind); - } - } - - @Override - public Register getFrameRegister() { - return rsp; - } - - public CalleeSaveLayout getCalleeSaveLayout() { - return csl; - } - - @Override - public String toString() { - return String.format("Allocatable: " + Arrays.toString(getAllocatableRegisters()) + "%n" + "CallerSave: " + Arrays.toString(getCallerSaveRegisters()) + "%n"); - } -} diff -r 5024c80224c7 -r e0b5d4fcd929 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64UncommonTrapStub.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64UncommonTrapStub.java Tue Jun 02 22:11:52 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64UncommonTrapStub.java Tue Jun 02 23:29:27 2015 +0200 @@ -32,6 +32,7 @@ import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.stubs.*; import com.oracle.jvmci.hotspot.*; +import com.oracle.jvmci.hotspot.amd64.*; final class AMD64UncommonTrapStub extends UncommonTrapStub { diff -r 5024c80224c7 -r e0b5d4fcd929 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/jvmci/AMD64HotSpotJVMCIBackendFactory.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/jvmci/AMD64HotSpotJVMCIBackendFactory.java Tue Jun 02 22:11:52 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/jvmci/AMD64HotSpotJVMCIBackendFactory.java Tue Jun 02 23:29:27 2015 +0200 @@ -26,11 +26,10 @@ import java.util.*; -import com.oracle.graal.hotspot.*; -import com.oracle.graal.hotspot.amd64.*; import com.oracle.jvmci.amd64.*; import com.oracle.jvmci.code.*; import com.oracle.jvmci.hotspot.*; +import com.oracle.jvmci.hotspot.amd64.*; import com.oracle.jvmci.meta.*; import com.oracle.jvmci.runtime.*; import com.oracle.jvmci.service.*; diff -r 5024c80224c7 -r e0b5d4fcd929 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCDeoptimizationStub.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCDeoptimizationStub.java Tue Jun 02 22:11:52 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCDeoptimizationStub.java Tue Jun 02 23:29:27 2015 +0200 @@ -25,6 +25,7 @@ import com.oracle.jvmci.code.TargetDescription; import com.oracle.jvmci.code.RegisterConfig; import com.oracle.jvmci.code.Register; +import com.oracle.jvmci.hotspot.sparc.*; import static com.oracle.jvmci.sparc.SPARC.*; diff -r 5024c80224c7 -r e0b5d4fcd929 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java Tue Jun 02 22:11:52 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,302 +0,0 @@ -/* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.hotspot.sparc; - -import com.oracle.jvmci.code.Architecture; -import com.oracle.jvmci.code.TargetDescription; -import com.oracle.jvmci.code.CallingConvention; -import com.oracle.jvmci.code.CalleeSaveLayout; -import com.oracle.jvmci.code.RegisterAttributes; -import com.oracle.jvmci.code.StackSlot; -import com.oracle.jvmci.code.RegisterConfig; -import com.oracle.jvmci.code.Register; -import com.oracle.jvmci.meta.Kind; -import com.oracle.jvmci.meta.JavaType; -import com.oracle.jvmci.meta.PlatformKind; -import com.oracle.jvmci.meta.Value; -import com.oracle.jvmci.meta.AllocatableValue; -import com.oracle.jvmci.sparc.*; - -import static com.oracle.jvmci.sparc.SPARC.*; - -import java.util.*; - -import com.oracle.jvmci.code.CallingConvention.Type; -import com.oracle.graal.asm.*; -import com.oracle.graal.lir.framemap.*; -import com.oracle.jvmci.common.*; -import com.oracle.jvmci.hotspot.*; - -public class SPARCHotSpotRegisterConfig implements RegisterConfig { - - private final Architecture architecture; - - private final Register[] allocatable; - - private final RegisterAttributes[] attributesMap; - - @Override - public Register[] getAllocatableRegisters() { - return allocatable.clone(); - } - - public Register[] filterAllocatableRegisters(PlatformKind kind, Register[] registers) { - ArrayList list = new ArrayList<>(); - for (Register reg : registers) { - if (architecture.canStoreValue(reg.getRegisterCategory(), kind)) { - // Special treatment for double precision - // TODO: This is wasteful it uses only half of the registers as float. - if (kind == Kind.Double) { - if (reg.name.startsWith("d")) { - list.add(reg); - } - } else if (kind == Kind.Float) { - if (reg.name.startsWith("f")) { - list.add(reg); - } - } else { - list.add(reg); - } - } - } - - Register[] ret = list.toArray(new Register[list.size()]); - return ret; - } - - @Override - public RegisterAttributes[] getAttributesMap() { - return attributesMap.clone(); - } - - private final Register[] cpuCallerParameterRegisters = {o0, o1, o2, o3, o4, o5}; - private final Register[] cpuCalleeParameterRegisters = {i0, i1, i2, i3, i4, i5}; - - private final Register[] fpuParameterRegisters = {f0, f1, f2, f3, f4, f5, f6, f7}; - private final Register[] fpuDoubleParameterRegisters = {d0, null, d2, null, d4, null, d6, null}; - // @formatter:off - private final Register[] callerSaveRegisters = - {g1, g2, g3, g4, g5, g6, g7, - o0, o1, o2, o3, o4, o5, o7, - f0, f1, f2, f3, f4, f5, f6, f7, - f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, - f24, f25, f26, f27, f28, f29, f30, f31, - d32, d34, d36, d38, d40, d42, d44, d46, - d48, d50, d52, d54, d56, d58, d60, d62}; - // @formatter:on - - /** - * Registers saved by the callee. This lists all L and I registers which are saved in the - * register window. {@link FrameMap} uses this array to calculate the spill area size. - */ - private final Register[] calleeSaveRegisters = {l0, l1, l2, l3, l4, l5, l6, l7, i0, i1, i2, i3, i4, i5, i6, i7}; - - private final CalleeSaveLayout csl; - - private static Register[] initAllocatable(boolean reserveForHeapBase) { - Register[] registers = null; - if (reserveForHeapBase) { - // @formatter:off - registers = new Register[]{ - // TODO this is not complete - // o7 cannot be used as register because it is always overwritten on call - // and the current register handler would ignore this fact if the called - // method still does not modify registers, in fact o7 is modified by the Call instruction - // There would be some extra handlin necessary to be able to handle the o7 properly for local usage - o0, o1, o2, o3, o4, o5, /*o6, o7,*/ - l0, l1, l2, l3, l4, l5, l6, l7, - i0, i1, i2, i3, i4, i5, /*i6,*/ /*i7,*/ - //f0, f1, f2, f3, f4, f5, f6, f7, - f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, - f24, f25, f26, f27, f28, f29, f30, f31, - d32, d34, d36, d38, d40, d42, d44, d46, - d48, d50, d52, d54, d56, d58, d60, d62 - }; - // @formatter:on - } else { - // @formatter:off - registers = new Register[]{ - // TODO this is not complete - o0, o1, o2, o3, o4, o5, /*o6, o7,*/ - l0, l1, l2, l3, l4, l5, l6, l7, - i0, i1, i2, i3, i4, i5, /*i6,*/ /*i7,*/ -// f0, f1, f2, f3, f4, f5, f6, f7 - f8, f9, f10, f11, f12, f13, f14, f15, - f16, f17, f18, f19, f20, f21, f22, f23, - f24, f25, f26, f27, f28, f29, f30, f31, - d32, d34, d36, d38, d40, d42, d44, d46, - d48, d50, d52, d54, d56, d58, d60, d62 - }; - // @formatter:on - } - - return registers; - } - - public SPARCHotSpotRegisterConfig(TargetDescription target, HotSpotVMConfig config) { - this(target, initAllocatable(config.useCompressedOops)); - } - - public SPARCHotSpotRegisterConfig(TargetDescription target, Register[] allocatable) { - this.architecture = target.arch; - - csl = new CalleeSaveLayout(target, -1, -1, target.arch.getWordSize(), calleeSaveRegisters); - this.allocatable = allocatable.clone(); - attributesMap = RegisterAttributes.createMap(this, SPARC.allRegisters); - } - - @Override - public Register[] getCallerSaveRegisters() { - return callerSaveRegisters; - } - - @Override - public boolean areAllAllocatableRegistersCallerSaved() { - return false; - } - - @Override - public Register getRegisterForRole(int index) { - throw new UnsupportedOperationException(); - } - - @Override - public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, TargetDescription target, boolean stackOnly) { - if (type == Type.JavaCall || type == Type.NativeCall) { - return callingConvention(cpuCallerParameterRegisters, returnType, parameterTypes, type, target, stackOnly); - } - if (type == Type.JavaCallee) { - return callingConvention(cpuCalleeParameterRegisters, returnType, parameterTypes, type, target, stackOnly); - } - throw JVMCIError.shouldNotReachHere(); - } - - public Register[] getCallingConventionRegisters(Type type, Kind kind) { - if (architecture.canStoreValue(FPUs, kind) || architecture.canStoreValue(FPUd, kind)) { - return fpuParameterRegisters; - } - assert architecture.canStoreValue(CPU, kind); - return type == Type.JavaCallee ? cpuCalleeParameterRegisters : cpuCallerParameterRegisters; - } - - private CallingConvention callingConvention(Register[] generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, Type type, TargetDescription target, boolean stackOnly) { - AllocatableValue[] locations = new AllocatableValue[parameterTypes.length]; - - int currentGeneral = 0; - int currentFloating = 0; - int currentStackOffset = 0; - - for (int i = 0; i < parameterTypes.length; i++) { - final Kind kind = parameterTypes[i].getKind(); - - switch (kind) { - case Byte: - case Boolean: - case Short: - case Char: - case Int: - case Long: - case Object: - if (!stackOnly && currentGeneral < generalParameterRegisters.length) { - Register register = generalParameterRegisters[currentGeneral++]; - locations[i] = register.asValue(target.getLIRKind(kind)); - } - break; - case Double: - if (!stackOnly && currentFloating < fpuParameterRegisters.length) { - if (currentFloating % 2 != 0) { - // Make register number even to be a double reg - currentFloating++; - } - Register register = fpuDoubleParameterRegisters[currentFloating]; - currentFloating += 2; // Only every second is a double register - locations[i] = register.asValue(target.getLIRKind(kind)); - } - break; - case Float: - if (!stackOnly && currentFloating < fpuParameterRegisters.length) { - Register register = fpuParameterRegisters[currentFloating++]; - locations[i] = register.asValue(target.getLIRKind(kind)); - } - break; - default: - throw JVMCIError.shouldNotReachHere(); - } - - if (locations[i] == null) { - // Stack slot is always aligned to its size in bytes but minimum wordsize - int typeSize = SPARC.spillSlotSize(target, kind); - currentStackOffset = NumUtil.roundUp(currentStackOffset, typeSize); - locations[i] = StackSlot.get(target.getLIRKind(kind.getStackKind()), currentStackOffset, !type.out); - currentStackOffset += typeSize; - } - } - - Kind returnKind = returnType == null ? Kind.Void : returnType.getKind(); - AllocatableValue returnLocation = returnKind == Kind.Void ? Value.ILLEGAL : getReturnRegister(returnKind, type).asValue(target.getLIRKind(returnKind.getStackKind())); - return new CallingConvention(currentStackOffset, returnLocation, locations); - } - - @Override - public Register getReturnRegister(Kind kind) { - return getReturnRegister(kind, Type.JavaCallee); - } - - private static Register getReturnRegister(Kind kind, Type type) { - switch (kind) { - case Boolean: - case Byte: - case Char: - case Short: - case Int: - case Long: - case Object: - return type == Type.JavaCallee ? i0 : o0; - case Float: - return f0; - case Double: - return d0; - case Void: - case Illegal: - return null; - default: - throw new UnsupportedOperationException("no return register for type " + kind); - } - } - - @Override - public Register getFrameRegister() { - return sp; - } - - public CalleeSaveLayout getCalleeSaveLayout() { - return csl; - } - - @Override - public String toString() { - return String.format("Allocatable: " + Arrays.toString(getAllocatableRegisters()) + "%n" + "CallerSave: " + Arrays.toString(getCallerSaveRegisters()) + "%n"); - } -} diff -r 5024c80224c7 -r e0b5d4fcd929 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCUncommonTrapStub.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCUncommonTrapStub.java Tue Jun 02 22:11:52 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCUncommonTrapStub.java Tue Jun 02 23:29:27 2015 +0200 @@ -25,6 +25,7 @@ import com.oracle.jvmci.code.TargetDescription; import com.oracle.jvmci.code.RegisterConfig; import com.oracle.jvmci.code.Register; +import com.oracle.jvmci.hotspot.sparc.*; import static com.oracle.jvmci.sparc.SPARC.*; diff -r 5024c80224c7 -r e0b5d4fcd929 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/jvmci/SPARCHotSpotJVMCIBackendFactory.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/jvmci/SPARCHotSpotJVMCIBackendFactory.java Tue Jun 02 22:11:52 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/jvmci/SPARCHotSpotJVMCIBackendFactory.java Tue Jun 02 23:29:27 2015 +0200 @@ -26,10 +26,9 @@ import java.util.*; -import com.oracle.graal.hotspot.*; -import com.oracle.graal.hotspot.sparc.*; import com.oracle.jvmci.code.*; import com.oracle.jvmci.hotspot.*; +import com.oracle.jvmci.hotspot.sparc.*; import com.oracle.jvmci.runtime.*; import com.oracle.jvmci.service.*; import com.oracle.jvmci.sparc.*; diff -r 5024c80224c7 -r e0b5d4fcd929 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotTargetDescription.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotTargetDescription.java Tue Jun 02 22:11:52 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.hotspot; - -import com.oracle.jvmci.code.TargetDescription; -import com.oracle.jvmci.code.Architecture; -import com.oracle.jvmci.code.ReferenceMap; -import com.oracle.jvmci.hotspot.*; - -public class HotSpotTargetDescription extends TargetDescription { - - public HotSpotTargetDescription(Architecture arch, boolean isMP, int stackAlignment, int implicitNullCheckLimit, boolean inlineObjects) { - super(arch, isMP, stackAlignment, implicitNullCheckLimit, inlineObjects); - } - - @Override - public ReferenceMap createReferenceMap(boolean hasRegisters, int stackSlotCount) { - return new HotSpotReferenceMap(hasRegisters ? arch.getRegisterReferenceMapSize() : 0, stackSlotCount, this); - } -} diff -r 5024c80224c7 -r e0b5d4fcd929 graal/com.oracle.jvmci.hotspot.amd64/src/com/oracle/jvmci/hotspot/amd64/AMD64HotSpotRegisterConfig.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.jvmci.hotspot.amd64/src/com/oracle/jvmci/hotspot/amd64/AMD64HotSpotRegisterConfig.java Tue Jun 02 23:29:27 2015 +0200 @@ -0,0 +1,268 @@ +/* + * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.jvmci.hotspot.amd64; + +import com.oracle.jvmci.amd64.*; +import com.oracle.jvmci.code.Register; +import com.oracle.jvmci.code.RegisterConfig; +import com.oracle.jvmci.code.TargetDescription; +import com.oracle.jvmci.code.CallingConvention; +import com.oracle.jvmci.code.StackSlot; +import com.oracle.jvmci.code.RegisterAttributes; +import com.oracle.jvmci.code.CalleeSaveLayout; +import com.oracle.jvmci.code.Architecture; +import com.oracle.jvmci.meta.JavaType; +import com.oracle.jvmci.meta.Value; +import com.oracle.jvmci.meta.PlatformKind; +import com.oracle.jvmci.meta.AllocatableValue; +import com.oracle.jvmci.meta.Kind; + +import static com.oracle.jvmci.amd64.AMD64.*; + +import java.util.*; + +import com.oracle.jvmci.code.CallingConvention.Type; +import com.oracle.jvmci.common.*; +import com.oracle.jvmci.hotspot.*; + +public class AMD64HotSpotRegisterConfig implements RegisterConfig { + + private final Architecture architecture; + + private final Register[] allocatable; + + private final int maxFrameSize; + + /** + * The caller saved registers always include all parameter registers. + */ + private final Register[] callerSaved; + + private final boolean allAllocatableAreCallerSaved; + + private final RegisterAttributes[] attributesMap; + + public int getMaximumFrameSize() { + return maxFrameSize; + } + + @Override + public Register[] getAllocatableRegisters() { + return allocatable.clone(); + } + + public Register[] filterAllocatableRegisters(PlatformKind kind, Register[] registers) { + ArrayList list = new ArrayList<>(); + for (Register reg : registers) { + if (architecture.canStoreValue(reg.getRegisterCategory(), kind)) { + list.add(reg); + } + } + + Register[] ret = list.toArray(new Register[list.size()]); + return ret; + } + + @Override + public RegisterAttributes[] getAttributesMap() { + return attributesMap.clone(); + } + + private final Register[] javaGeneralParameterRegisters; + private final Register[] nativeGeneralParameterRegisters; + private final Register[] xmmParameterRegisters = {xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7}; + + /* + * Some ABIs (e.g. Windows) require a so-called "home space", that is a save area on the stack + * to store the argument registers + */ + private final boolean needsNativeStackHomeSpace; + + private final CalleeSaveLayout csl; + + private static Register[] initAllocatable(boolean reserveForHeapBase) { + Register[] registers = null; + // @formatter:off + if (reserveForHeapBase) { + registers = new Register[] { + rax, rbx, rcx, rdx, /*rsp,*/ rbp, rsi, rdi, r8, r9, r10, r11, /*r12,*/ r13, r14, /*r15, */ + xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, + xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 + }; + } else { + registers = new Register[] { + rax, rbx, rcx, rdx, /*rsp,*/ rbp, rsi, rdi, r8, r9, r10, r11, r12, r13, r14, /*r15, */ + xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, + xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 + }; + } + // @formatter:on + return registers; + } + + public AMD64HotSpotRegisterConfig(Architecture architecture, HotSpotVMConfig config) { + this(architecture, config, initAllocatable(config.useCompressedOops)); + assert callerSaved.length >= allocatable.length; + } + + public AMD64HotSpotRegisterConfig(Architecture architecture, HotSpotVMConfig config, Register[] allocatable) { + this.architecture = architecture; + this.maxFrameSize = config.maxFrameSize; + + if (config.windowsOs) { + javaGeneralParameterRegisters = new Register[]{rdx, r8, r9, rdi, rsi, rcx}; + nativeGeneralParameterRegisters = new Register[]{rcx, rdx, r8, r9}; + this.needsNativeStackHomeSpace = true; + } else { + javaGeneralParameterRegisters = new Register[]{rsi, rdx, rcx, r8, r9, rdi}; + nativeGeneralParameterRegisters = new Register[]{rdi, rsi, rdx, rcx, r8, r9}; + this.needsNativeStackHomeSpace = false; + } + + csl = null; + this.allocatable = allocatable.clone(); + Set callerSaveSet = new HashSet<>(); + Collections.addAll(callerSaveSet, allocatable); + Collections.addAll(callerSaveSet, xmmParameterRegisters); + Collections.addAll(callerSaveSet, javaGeneralParameterRegisters); + Collections.addAll(callerSaveSet, nativeGeneralParameterRegisters); + callerSaved = callerSaveSet.toArray(new Register[callerSaveSet.size()]); + + allAllocatableAreCallerSaved = true; + attributesMap = RegisterAttributes.createMap(this, AMD64.allRegisters); + } + + @Override + public Register[] getCallerSaveRegisters() { + return callerSaved; + } + + @Override + public boolean areAllAllocatableRegistersCallerSaved() { + return allAllocatableAreCallerSaved; + } + + @Override + public Register getRegisterForRole(int index) { + throw new UnsupportedOperationException(); + } + + @Override + public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, TargetDescription target, boolean stackOnly) { + if (type == Type.NativeCall) { + return callingConvention(nativeGeneralParameterRegisters, returnType, parameterTypes, type, target, stackOnly); + } + // On x64, parameter locations are the same whether viewed + // from the caller or callee perspective + return callingConvention(javaGeneralParameterRegisters, returnType, parameterTypes, type, target, stackOnly); + } + + public Register[] getCallingConventionRegisters(Type type, Kind kind) { + if (architecture.canStoreValue(XMM, kind)) { + return xmmParameterRegisters; + } + assert architecture.canStoreValue(CPU, kind); + return type == Type.NativeCall ? nativeGeneralParameterRegisters : javaGeneralParameterRegisters; + } + + private CallingConvention callingConvention(Register[] generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, Type type, TargetDescription target, boolean stackOnly) { + AllocatableValue[] locations = new AllocatableValue[parameterTypes.length]; + + int currentGeneral = 0; + int currentXMM = 0; + int currentStackOffset = type == Type.NativeCall && needsNativeStackHomeSpace ? generalParameterRegisters.length * target.wordSize : 0; + + for (int i = 0; i < parameterTypes.length; i++) { + final Kind kind = parameterTypes[i].getKind(); + + switch (kind) { + case Byte: + case Boolean: + case Short: + case Char: + case Int: + case Long: + case Object: + if (!stackOnly && currentGeneral < generalParameterRegisters.length) { + Register register = generalParameterRegisters[currentGeneral++]; + locations[i] = register.asValue(target.getLIRKind(kind)); + } + break; + case Float: + case Double: + if (!stackOnly && currentXMM < xmmParameterRegisters.length) { + Register register = xmmParameterRegisters[currentXMM++]; + locations[i] = register.asValue(target.getLIRKind(kind)); + } + break; + default: + throw JVMCIError.shouldNotReachHere(); + } + + if (locations[i] == null) { + locations[i] = StackSlot.get(target.getLIRKind(kind.getStackKind()), currentStackOffset, !type.out); + currentStackOffset += Math.max(target.getSizeInBytes(kind), target.wordSize); + } + } + + Kind returnKind = returnType == null ? Kind.Void : returnType.getKind(); + AllocatableValue returnLocation = returnKind == Kind.Void ? Value.ILLEGAL : getReturnRegister(returnKind).asValue(target.getLIRKind(returnKind.getStackKind())); + return new CallingConvention(currentStackOffset, returnLocation, locations); + } + + @Override + public Register getReturnRegister(Kind kind) { + switch (kind) { + case Boolean: + case Byte: + case Char: + case Short: + case Int: + case Long: + case Object: + return rax; + case Float: + case Double: + return xmm0; + case Void: + case Illegal: + return null; + default: + throw new UnsupportedOperationException("no return register for type " + kind); + } + } + + @Override + public Register getFrameRegister() { + return rsp; + } + + public CalleeSaveLayout getCalleeSaveLayout() { + return csl; + } + + @Override + public String toString() { + return String.format("Allocatable: " + Arrays.toString(getAllocatableRegisters()) + "%n" + "CallerSave: " + Arrays.toString(getCallerSaveRegisters()) + "%n"); + } +} diff -r 5024c80224c7 -r e0b5d4fcd929 graal/com.oracle.jvmci.hotspot.sparc/src/com/oracle/jvmci/hotspot/sparc/SPARCHotSpotRegisterConfig.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.jvmci.hotspot.sparc/src/com/oracle/jvmci/hotspot/sparc/SPARCHotSpotRegisterConfig.java Tue Jun 02 23:29:27 2015 +0200 @@ -0,0 +1,304 @@ +/* + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.jvmci.hotspot.sparc; + +import com.oracle.jvmci.code.Architecture; +import com.oracle.jvmci.code.TargetDescription; +import com.oracle.jvmci.code.CallingConvention; +import com.oracle.jvmci.code.CalleeSaveLayout; +import com.oracle.jvmci.code.RegisterAttributes; +import com.oracle.jvmci.code.StackSlot; +import com.oracle.jvmci.code.RegisterConfig; +import com.oracle.jvmci.code.Register; +import com.oracle.jvmci.meta.Kind; +import com.oracle.jvmci.meta.JavaType; +import com.oracle.jvmci.meta.PlatformKind; +import com.oracle.jvmci.meta.Value; +import com.oracle.jvmci.meta.AllocatableValue; +import com.oracle.jvmci.sparc.*; + +import static com.oracle.jvmci.sparc.SPARC.*; + +import java.util.*; + +import com.oracle.jvmci.code.CallingConvention.Type; +import com.oracle.jvmci.common.*; +import com.oracle.jvmci.hotspot.*; + +public class SPARCHotSpotRegisterConfig implements RegisterConfig { + + private final Architecture architecture; + + private final Register[] allocatable; + + private final RegisterAttributes[] attributesMap; + + @Override + public Register[] getAllocatableRegisters() { + return allocatable.clone(); + } + + public Register[] filterAllocatableRegisters(PlatformKind kind, Register[] registers) { + ArrayList list = new ArrayList<>(); + for (Register reg : registers) { + if (architecture.canStoreValue(reg.getRegisterCategory(), kind)) { + // Special treatment for double precision + // TODO: This is wasteful it uses only half of the registers as float. + if (kind == Kind.Double) { + if (reg.name.startsWith("d")) { + list.add(reg); + } + } else if (kind == Kind.Float) { + if (reg.name.startsWith("f")) { + list.add(reg); + } + } else { + list.add(reg); + } + } + } + + Register[] ret = list.toArray(new Register[list.size()]); + return ret; + } + + @Override + public RegisterAttributes[] getAttributesMap() { + return attributesMap.clone(); + } + + private final Register[] cpuCallerParameterRegisters = {o0, o1, o2, o3, o4, o5}; + private final Register[] cpuCalleeParameterRegisters = {i0, i1, i2, i3, i4, i5}; + + private final Register[] fpuParameterRegisters = {f0, f1, f2, f3, f4, f5, f6, f7}; + private final Register[] fpuDoubleParameterRegisters = {d0, null, d2, null, d4, null, d6, null}; + // @formatter:off + private final Register[] callerSaveRegisters = + {g1, g2, g3, g4, g5, g6, g7, + o0, o1, o2, o3, o4, o5, o7, + f0, f1, f2, f3, f4, f5, f6, f7, + f8, f9, f10, f11, f12, f13, f14, f15, + f16, f17, f18, f19, f20, f21, f22, f23, + f24, f25, f26, f27, f28, f29, f30, f31, + d32, d34, d36, d38, d40, d42, d44, d46, + d48, d50, d52, d54, d56, d58, d60, d62}; + // @formatter:on + + /** + * Registers saved by the callee. This lists all L and I registers which are saved in the + * register window. + */ + private final Register[] calleeSaveRegisters = {l0, l1, l2, l3, l4, l5, l6, l7, i0, i1, i2, i3, i4, i5, i6, i7}; + + private final CalleeSaveLayout csl; + + private static Register[] initAllocatable(boolean reserveForHeapBase) { + Register[] registers = null; + if (reserveForHeapBase) { + // @formatter:off + registers = new Register[]{ + // TODO this is not complete + // o7 cannot be used as register because it is always overwritten on call + // and the current register handler would ignore this fact if the called + // method still does not modify registers, in fact o7 is modified by the Call instruction + // There would be some extra handlin necessary to be able to handle the o7 properly for local usage + o0, o1, o2, o3, o4, o5, /*o6, o7,*/ + l0, l1, l2, l3, l4, l5, l6, l7, + i0, i1, i2, i3, i4, i5, /*i6,*/ /*i7,*/ + //f0, f1, f2, f3, f4, f5, f6, f7, + f8, f9, f10, f11, f12, f13, f14, f15, + f16, f17, f18, f19, f20, f21, f22, f23, + f24, f25, f26, f27, f28, f29, f30, f31, + d32, d34, d36, d38, d40, d42, d44, d46, + d48, d50, d52, d54, d56, d58, d60, d62 + }; + // @formatter:on + } else { + // @formatter:off + registers = new Register[]{ + // TODO this is not complete + o0, o1, o2, o3, o4, o5, /*o6, o7,*/ + l0, l1, l2, l3, l4, l5, l6, l7, + i0, i1, i2, i3, i4, i5, /*i6,*/ /*i7,*/ +// f0, f1, f2, f3, f4, f5, f6, f7 + f8, f9, f10, f11, f12, f13, f14, f15, + f16, f17, f18, f19, f20, f21, f22, f23, + f24, f25, f26, f27, f28, f29, f30, f31, + d32, d34, d36, d38, d40, d42, d44, d46, + d48, d50, d52, d54, d56, d58, d60, d62 + }; + // @formatter:on + } + + return registers; + } + + public SPARCHotSpotRegisterConfig(TargetDescription target, HotSpotVMConfig config) { + this(target, initAllocatable(config.useCompressedOops)); + } + + public SPARCHotSpotRegisterConfig(TargetDescription target, Register[] allocatable) { + this.architecture = target.arch; + + csl = new CalleeSaveLayout(target, -1, -1, target.arch.getWordSize(), calleeSaveRegisters); + this.allocatable = allocatable.clone(); + attributesMap = RegisterAttributes.createMap(this, SPARC.allRegisters); + } + + @Override + public Register[] getCallerSaveRegisters() { + return callerSaveRegisters; + } + + @Override + public boolean areAllAllocatableRegistersCallerSaved() { + return false; + } + + @Override + public Register getRegisterForRole(int index) { + throw new UnsupportedOperationException(); + } + + @Override + public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, TargetDescription target, boolean stackOnly) { + if (type == Type.JavaCall || type == Type.NativeCall) { + return callingConvention(cpuCallerParameterRegisters, returnType, parameterTypes, type, target, stackOnly); + } + if (type == Type.JavaCallee) { + return callingConvention(cpuCalleeParameterRegisters, returnType, parameterTypes, type, target, stackOnly); + } + throw JVMCIError.shouldNotReachHere(); + } + + public Register[] getCallingConventionRegisters(Type type, Kind kind) { + if (architecture.canStoreValue(FPUs, kind) || architecture.canStoreValue(FPUd, kind)) { + return fpuParameterRegisters; + } + assert architecture.canStoreValue(CPU, kind); + return type == Type.JavaCallee ? cpuCalleeParameterRegisters : cpuCallerParameterRegisters; + } + + private CallingConvention callingConvention(Register[] generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, Type type, TargetDescription target, boolean stackOnly) { + AllocatableValue[] locations = new AllocatableValue[parameterTypes.length]; + + int currentGeneral = 0; + int currentFloating = 0; + int currentStackOffset = 0; + + for (int i = 0; i < parameterTypes.length; i++) { + final Kind kind = parameterTypes[i].getKind(); + + switch (kind) { + case Byte: + case Boolean: + case Short: + case Char: + case Int: + case Long: + case Object: + if (!stackOnly && currentGeneral < generalParameterRegisters.length) { + Register register = generalParameterRegisters[currentGeneral++]; + locations[i] = register.asValue(target.getLIRKind(kind)); + } + break; + case Double: + if (!stackOnly && currentFloating < fpuParameterRegisters.length) { + if (currentFloating % 2 != 0) { + // Make register number even to be a double reg + currentFloating++; + } + Register register = fpuDoubleParameterRegisters[currentFloating]; + currentFloating += 2; // Only every second is a double register + locations[i] = register.asValue(target.getLIRKind(kind)); + } + break; + case Float: + if (!stackOnly && currentFloating < fpuParameterRegisters.length) { + Register register = fpuParameterRegisters[currentFloating++]; + locations[i] = register.asValue(target.getLIRKind(kind)); + } + break; + default: + throw JVMCIError.shouldNotReachHere(); + } + + if (locations[i] == null) { + // Stack slot is always aligned to its size in bytes but minimum wordsize + int typeSize = SPARC.spillSlotSize(target, kind); + currentStackOffset = roundUp(currentStackOffset, typeSize); + locations[i] = StackSlot.get(target.getLIRKind(kind.getStackKind()), currentStackOffset, !type.out); + currentStackOffset += typeSize; + } + } + + Kind returnKind = returnType == null ? Kind.Void : returnType.getKind(); + AllocatableValue returnLocation = returnKind == Kind.Void ? Value.ILLEGAL : getReturnRegister(returnKind, type).asValue(target.getLIRKind(returnKind.getStackKind())); + return new CallingConvention(currentStackOffset, returnLocation, locations); + } + + private static int roundUp(int number, int mod) { + return ((number + mod - 1) / mod) * mod; + } + + @Override + public Register getReturnRegister(Kind kind) { + return getReturnRegister(kind, Type.JavaCallee); + } + + private static Register getReturnRegister(Kind kind, Type type) { + switch (kind) { + case Boolean: + case Byte: + case Char: + case Short: + case Int: + case Long: + case Object: + return type == Type.JavaCallee ? i0 : o0; + case Float: + return f0; + case Double: + return d0; + case Void: + case Illegal: + return null; + default: + throw new UnsupportedOperationException("no return register for type " + kind); + } + } + + @Override + public Register getFrameRegister() { + return sp; + } + + public CalleeSaveLayout getCalleeSaveLayout() { + return csl; + } + + @Override + public String toString() { + return String.format("Allocatable: " + Arrays.toString(getAllocatableRegisters()) + "%n" + "CallerSave: " + Arrays.toString(getCallerSaveRegisters()) + "%n"); + } +} diff -r 5024c80224c7 -r e0b5d4fcd929 graal/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotTargetDescription.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotTargetDescription.java Tue Jun 02 23:29:27 2015 +0200 @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.jvmci.hotspot; + +import com.oracle.jvmci.code.*; + +public class HotSpotTargetDescription extends TargetDescription { + + public HotSpotTargetDescription(Architecture arch, boolean isMP, int stackAlignment, int implicitNullCheckLimit, boolean inlineObjects) { + super(arch, isMP, stackAlignment, implicitNullCheckLimit, inlineObjects); + } + + @Override + public ReferenceMap createReferenceMap(boolean hasRegisters, int stackSlotCount) { + return new HotSpotReferenceMap(hasRegisters ? arch.getRegisterReferenceMapSize() : 0, stackSlotCount, this); + } +} diff -r 5024c80224c7 -r e0b5d4fcd929 mx/suite.py --- a/mx/suite.py Tue Jun 02 22:11:52 2015 +0200 +++ b/mx/suite.py Tue Jun 02 23:29:27 2015 +0200 @@ -153,15 +153,15 @@ }, "projects" : { - + # ------------- JVMCI ------------- - + "com.oracle.jvmci.service" : { "subDir" : "graal", "sourceDirs" : ["src"], "checkstyle" : "com.oracle.graal.graph", "javaCompliance" : "1.8", - "workingSets" : "API,Graal", + "workingSets" : "API,JVMCI", }, "com.oracle.jvmci.service.processor" : { @@ -170,7 +170,7 @@ "dependencies" : ["com.oracle.jvmci.service"], "checkstyle" : "com.oracle.graal.graph", "javaCompliance" : "1.8", - "workingSets" : "Codegen,HotSpot", + "workingSets" : "JVMCI,Codegen,HotSpot", }, "com.oracle.jvmci.common" : { @@ -256,7 +256,7 @@ "dependencies" : ["com.oracle.jvmci.hotspotvmconfig", "com.oracle.jvmci.common"], "checkstyle" : "com.oracle.graal.graph", "javaCompliance" : "1.8", - "workingSets" : "Graal,HotSpot,Codegen", + "workingSets" : "JVMCI,HotSpot,Codegen", }, "com.oracle.jvmci.debug" : { @@ -337,7 +337,20 @@ "dependencies" : ["com.oracle.jvmci.code"], "checkstyle" : "com.oracle.graal.graph", "javaCompliance" : "1.8", - "workingSets" : "Graal,AMD64", + "workingSets" : "JVMCI,AMD64", + }, + + "com.oracle.jvmci.hotspot.amd64" : { + "subDir" : "graal", + "sourceDirs" : ["src"], + "dependencies" : [ + "com.oracle.jvmci.amd64", + "com.oracle.jvmci.hotspot", + ], + "checkstyle" : "com.oracle.graal.graph", + "annotationProcessors" : ["com.oracle.jvmci.service.processor"], + "javaCompliance" : "1.8", + "workingSets" : "JVMCI,HotSpot,AMD64", }, "com.oracle.jvmci.sparc" : { @@ -346,11 +359,24 @@ "dependencies" : ["com.oracle.jvmci.code"], "checkstyle" : "com.oracle.graal.graph", "javaCompliance" : "1.8", - "workingSets" : "Graal,SPARC", + "workingSets" : "JVMCI,SPARC", + }, + + "com.oracle.jvmci.hotspot.sparc" : { + "subDir" : "graal", + "sourceDirs" : ["src"], + "dependencies" : [ + "com.oracle.jvmci.sparc", + "com.oracle.jvmci.hotspot", + ], + "checkstyle" : "com.oracle.graal.graph", + "annotationProcessors" : ["com.oracle.jvmci.service.processor"], + "javaCompliance" : "1.8", + "workingSets" : "JVMCI,HotSpot,SPARC", }, # ------------- NFI ------------- - + "com.oracle.nfi" : { "subDir" : "graal", "sourceDirs" : ["src"], @@ -372,7 +398,7 @@ }, # ------------- Graal ------------- - + "com.oracle.graal.api.collections" : { "subDir" : "graal", "sourceDirs" : ["src"], @@ -454,6 +480,7 @@ "subDir" : "graal", "sourceDirs" : ["src"], "dependencies" : [ + "com.oracle.jvmci.hotspot.amd64", "com.oracle.graal.compiler.amd64", "com.oracle.graal.hotspot", "com.oracle.graal.replacements.amd64", @@ -468,6 +495,7 @@ "subDir" : "graal", "sourceDirs" : ["src"], "dependencies" : [ + "com.oracle.jvmci.hotspot.sparc", "com.oracle.graal.compiler.sparc", "com.oracle.graal.replacements.sparc", ], @@ -1009,7 +1037,7 @@ }, # ------------- Truffle ------------- - + "com.oracle.truffle.api" : { "subDir" : "graal", "sourceDirs" : ["src"], @@ -1189,7 +1217,7 @@ }, # ------------- GraalTruffle ------------- - + "com.oracle.graal.truffle" : { "subDir" : "graal", "sourceDirs" : ["src"],