diff graal/com.oracle.max.cri/src/com/sun/cri/ci/CiRegisterConfig.java @ 3733:e233f5660da4

Added Java files from Maxine project.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Sat, 17 Dec 2011 19:59:18 +0100
parents
children 319860ae697a
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/sun/cri/ci/CiRegisterConfig.java	Sat Dec 17 19:59:18 2011 +0100
@@ -0,0 +1,299 @@
+/*
+ * Copyright (c) 2010, 2011, 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.sun.cri.ci;
+
+import java.util.*;
+
+import com.sun.cri.ci.CiCallingConvention.Type;
+import com.sun.cri.ci.CiRegister.RegisterFlag;
+import com.sun.cri.ri.*;
+
+/**
+ * A default implementation of {@link RiRegisterConfig}.
+ */
+public class CiRegisterConfig implements RiRegisterConfig {
+
+    /**
+     * The object describing the callee save area of this register configuration.
+     */
+    public CiCalleeSaveLayout csl;
+
+    /**
+     * The minimum register role identifier.
+     */
+    public final int minRole;
+
+    /**
+     * The map from register role IDs to registers.
+     */
+    public final CiRegister[] registersRoleMap;
+
+    /**
+     * The set of registers that can be used by the register allocator.
+     */
+    public final CiRegister[] allocatable;
+
+    /**
+     * The set of registers that can be used by the register allocator,
+     * {@linkplain CiRegister#categorize(CiRegister[]) categorized} by register
+     * {@linkplain RegisterFlag flags}.
+     */
+    public final EnumMap<RegisterFlag, CiRegister[]> categorized;
+
+    /**
+     * The ordered set of registers used to pass integral arguments.
+     */
+    public final CiRegister[] cpuParameters;
+
+    /**
+     * The ordered set of registers used to pass floating point arguments.
+     */
+    public final CiRegister[] fpuParameters;
+
+    /**
+     * The caller saved registers.
+     */
+    public final CiRegister[] callerSave;
+
+    /**
+     * The register to which {@link CiRegister#Frame} and {@link CiRegister#CallerFrame} are bound.
+     */
+    public final CiRegister frame;
+
+    /**
+     * Register for returning an integral value.
+     */
+    public final CiRegister integralReturn;
+
+    /**
+     * Register for returning a floating point value.
+     */
+    public final CiRegister floatingPointReturn;
+
+    /**
+     * The map from register {@linkplain CiRegister#number numbers} to register
+     * {@linkplain RiRegisterAttributes attributes} for this register configuration.
+     */
+    public final RiRegisterAttributes[] attributesMap;
+
+    /**
+     * The scratch register.
+     */
+    public final CiRegister scratch;
+
+    /**
+     * The frame offset of the first stack argument for each calling convention {@link CiCallingConvention.Type}.
+     */
+    public final int[] stackArg0Offsets = new int[CiCallingConvention.Type.VALUES.length];
+
+    public CiRegisterConfig(
+                    CiRegister frame,
+                    CiRegister integralReturn,
+                    CiRegister floatingPointReturn,
+                    CiRegister scratch,
+                    CiRegister[] allocatable,
+                    CiRegister[] callerSave,
+                    CiRegister[] parameters,
+                    CiCalleeSaveLayout csl,
+                    CiRegister[] allRegisters,
+                    Map<Integer, CiRegister> roles) {
+        this.frame = frame;
+        this.csl = csl;
+        this.allocatable = allocatable;
+        this.callerSave = callerSave;
+        assert !Arrays.asList(allocatable).contains(scratch);
+        this.scratch = scratch;
+        EnumMap<RegisterFlag, CiRegister[]> categorizedParameters = CiRegister.categorize(parameters);
+        this.cpuParameters = categorizedParameters.get(RegisterFlag.CPU);
+        this.fpuParameters = categorizedParameters.get(RegisterFlag.FPU);
+        categorized = CiRegister.categorize(allocatable);
+        attributesMap = RiRegisterAttributes.createMap(this, allRegisters);
+        this.floatingPointReturn = floatingPointReturn;
+        this.integralReturn = integralReturn;
+        int minRoleId = Integer.MAX_VALUE;
+        int maxRoleId = Integer.MIN_VALUE;
+        for (Map.Entry<Integer, CiRegister> e : roles.entrySet()) {
+            int id = e.getKey();
+            assert id >= 0;
+            if (minRoleId > id) {
+                minRoleId = id;
+            }
+            if (maxRoleId < id) {
+                maxRoleId = id;
+            }
+        }
+        registersRoleMap = new CiRegister[(maxRoleId - minRoleId) + 1];
+        for (Map.Entry<Integer, CiRegister> e : roles.entrySet()) {
+            int id = e.getKey();
+            registersRoleMap[id] = e.getValue();
+        }
+        minRole = minRoleId;
+    }
+
+    public CiRegisterConfig(CiRegisterConfig src, CiCalleeSaveLayout csl) {
+        this.frame = src.frame;
+        this.csl = csl;
+        this.allocatable = src.allocatable;
+        this.callerSave = src.callerSave;
+        this.scratch = src.scratch;
+        this.cpuParameters = src.cpuParameters;
+        this.fpuParameters = src.fpuParameters;
+        this.categorized = src.categorized;
+        this.attributesMap = src.attributesMap;
+        this.floatingPointReturn = src.floatingPointReturn;
+        this.integralReturn = src.integralReturn;
+        this.registersRoleMap = src.registersRoleMap;
+        this.minRole = src.minRole;
+        System.arraycopy(src.stackArg0Offsets, 0, stackArg0Offsets, 0, stackArg0Offsets.length);
+    }
+
+    public CiRegister getReturnRegister(CiKind kind) {
+        if (kind.isDouble() || kind.isFloat()) {
+            return floatingPointReturn;
+        }
+        return integralReturn;
+    }
+
+    public CiRegister getFrameRegister() {
+        return frame;
+    }
+
+    public CiRegister getScratchRegister() {
+        return scratch;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * This implementation assigns all available registers to parameters before assigning
+     * any stack slots to parameters.
+     */
+    public CiCallingConvention getCallingConvention(Type type, CiKind[] parameters, CiTarget target, boolean stackOnly) {
+        CiValue[] locations = new CiValue[parameters.length];
+
+        int currentGeneral = 0;
+        int currentXMM = 0;
+        int firstStackIndex = (stackArg0Offsets[type.ordinal()]) / target.spillSlotSize;
+        int currentStackIndex = firstStackIndex;
+
+        for (int i = 0; i < parameters.length; i++) {
+            final CiKind kind = parameters[i];
+
+            switch (kind) {
+                case Byte:
+                case Boolean:
+                case Short:
+                case Char:
+                case Int:
+                case Long:
+                case Object:
+                    if (!stackOnly && currentGeneral < cpuParameters.length) {
+                        CiRegister register = cpuParameters[currentGeneral++];
+                        locations[i] = register.asValue(kind);
+                    }
+                    break;
+
+                case Float:
+                case Double:
+                    if (!stackOnly && currentXMM < fpuParameters.length) {
+                        CiRegister register = fpuParameters[currentXMM++];
+                        locations[i] = register.asValue(kind);
+                    }
+                    break;
+
+                default:
+                    throw new InternalError("Unexpected parameter kind: " + kind);
+            }
+
+            if (locations[i] == null) {
+                locations[i] = CiStackSlot.get(kind.stackKind(), currentStackIndex, !type.out);
+                currentStackIndex += target.spillSlots(kind);
+            }
+        }
+
+        return new CiCallingConvention(locations, (currentStackIndex - firstStackIndex) * target.spillSlotSize);
+    }
+
+    public CiRegister[] getCallingConventionRegisters(Type type, RegisterFlag flag) {
+        if (flag == RegisterFlag.CPU) {
+            return cpuParameters;
+        }
+        assert flag == RegisterFlag.FPU;
+        return fpuParameters;
+    }
+
+    public CiRegister[] getAllocatableRegisters() {
+        return allocatable;
+    }
+
+    public EnumMap<RegisterFlag, CiRegister[]> getCategorizedAllocatableRegisters() {
+        return categorized;
+    }
+
+    public CiRegister[] getCallerSaveRegisters() {
+        return callerSave;
+    }
+
+    public CiCalleeSaveLayout getCalleeSaveLayout() {
+        return csl;
+    }
+
+    public RiRegisterAttributes[] getAttributesMap() {
+        return attributesMap;
+    }
+
+    public CiRegister getRegisterForRole(int id) {
+        return registersRoleMap[id - minRole];
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder roleMap = new StringBuilder();
+        for (int i = 0; i < registersRoleMap.length; ++i) {
+            CiRegister reg = registersRoleMap[i];
+            if (reg != null) {
+                if (roleMap.length() != 0) {
+                    roleMap.append(", ");
+                }
+                roleMap.append(i + minRole).append(" -> ").append(reg);
+            }
+        }
+        StringBuilder stackArg0OffsetsMap = new StringBuilder();
+        for (Type t : Type.VALUES) {
+            if (stackArg0OffsetsMap.length() != 0) {
+                stackArg0OffsetsMap.append(", ");
+            }
+            stackArg0OffsetsMap.append(t).append(" -> ").append(stackArg0Offsets[t.ordinal()]);
+        }
+        String res = String.format(
+             "Allocatable: " + Arrays.toString(getAllocatableRegisters()) + "%n" +
+             "CallerSave:  " + Arrays.toString(getCallerSaveRegisters()) + "%n" +
+             "CalleeSave:  " + getCalleeSaveLayout() + "%n" +
+             "CPU Params:  " + Arrays.toString(cpuParameters) + "%n" +
+             "FPU Params:  " + Arrays.toString(fpuParameters) + "%n" +
+             "VMRoles:     " + roleMap + "%n" +
+             "stackArg0:   " + stackArg0OffsetsMap + "%n" +
+             "Scratch:     " + getScratchRegister() + "%n");
+        return res;
+    }
+}