changeset 21674:e0b5d4fcd929

moved HotSpotTargetDescription and [AMD64|SPARC]HotSpotRegisterConfig into JVMCI namespace (JBS:GRAAL-53)
author Doug Simon <doug.simon@oracle.com>
date Tue, 02 Jun 2015 23:29:27 +0200
parents 5024c80224c7
children 2e8c01def9a5
files graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DeoptimizationStub.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64UncommonTrapStub.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/jvmci/AMD64HotSpotJVMCIBackendFactory.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCDeoptimizationStub.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCUncommonTrapStub.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/jvmci/SPARCHotSpotJVMCIBackendFactory.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotTargetDescription.java graal/com.oracle.jvmci.amd64/src/com/oracle/jvmci/amd64/AMD64.java graal/com.oracle.jvmci.hotspot.amd64/src/com/oracle/jvmci/hotspot/amd64/AMD64HotSpotRegisterConfig.java graal/com.oracle.jvmci.hotspot.sparc/src/com/oracle/jvmci/hotspot/sparc/SPARCHotSpotRegisterConfig.java graal/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotTargetDescription.java graal/com.oracle.jvmci.sparc/src/com/oracle/jvmci/sparc/SPARC.java mx/suite.py
diffstat 13 files changed, 654 insertions(+), 629 deletions(-) [+]
line wrap: on
line diff
--- 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 {
 
--- 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<Register> 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<Register> 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");
-    }
-}
--- 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 {
 
--- 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.*;
--- 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.*;
 
--- 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<Register> 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");
-    }
-}
--- 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.*;
 
--- 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.*;
--- 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);
-    }
-}
--- /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<Register> 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<Register> 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");
+    }
+}
--- /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<Register> 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");
+    }
+}
--- /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);
+    }
+}
--- 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"],