diff graal/com.oracle.max.cri/src/com/sun/cri/ci/CiCalleeSaveLayout.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 bc8527f3071c
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/CiCalleeSaveLayout.java	Sat Dec 17 19:59:18 2011 +0100
@@ -0,0 +1,179 @@
+/*
+ * 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.*;
+
+
+/**
+ * The callee save area (CSA) is a contiguous space in a stack frame
+ * used to save (and restore) the values of the caller's registers.
+ * This class describes the layout of a CSA in terms of its
+ * {@linkplain #size size}, {@linkplain #slotSize slot size} and
+ * the {@linkplain #registers callee save registers} covered by the CSA.
+ */
+public class CiCalleeSaveLayout {
+
+    /**
+     * The size (in bytes) of the CSA.
+     */
+    public final int size;
+
+    /**
+     * The size (in bytes) of an {@linkplain #registerAtIndex(int) indexable} slot in the CSA.
+     */
+    public final int slotSize;
+
+    /**
+     * Map from {@linkplain CiRegister#number register numbers} to slot indexes in the CSA.
+     */
+    private final int[] regNumToIndex;
+
+    private final CiRegister[] indexToReg;
+
+    /**
+     * The list of registers {@linkplain #contains(CiRegister) contained} by this CSA.
+     */
+    public final CiRegister[] registers;
+
+    /**
+     * The offset from the frame pointer to the CSA. If this is not known, then this field
+     * will have the value {@link Integer#MAX_VALUE}.
+     */
+    public final int frameOffsetToCSA;
+
+    /**
+     * Creates a CSA layout.
+     *
+     * @param size size (in bytes) of the CSA. If this is {@code -1}, then the CSA size will be computed from {@code registers}.
+     * @param slotSize the size (in bytes) of an {@linkplain #registerAtIndex(int) indexable} slot in the CSA
+     * @param registers the registers that can be saved in the CSA
+     */
+    public CiCalleeSaveLayout(int frameOffsetToCSA, int size, int slotSize, CiRegister... registers) {
+        this.frameOffsetToCSA = frameOffsetToCSA;
+        assert slotSize == 0 || CiUtil.isPowerOf2(slotSize);
+        this.slotSize = slotSize;
+        int maxRegNum = -1;
+        int maxOffset = 0;
+        this.registers = registers;
+        int offset = 0;
+        for (CiRegister reg : registers) {
+            assert offset % slotSize == 0;
+            assert reg.number >= 0;
+            if (reg.number > maxRegNum) {
+                maxRegNum = reg.number;
+            }
+            if (offset > maxOffset) {
+                maxOffset = offset;
+            }
+            offset += reg.spillSlotSize;
+        }
+        if (size == -1) {
+            this.size = offset;
+        } else {
+            assert offset <= size;
+            this.size = size;
+        }
+        size = this.size;
+
+        this.regNumToIndex = new int[maxRegNum + 1];
+        this.indexToReg = offset == 0 ? new CiRegister[0] : new CiRegister[offset / slotSize];
+        Arrays.fill(regNumToIndex, -1);
+        offset = 0;
+        for (CiRegister reg : registers) {
+            int index = offset / slotSize;
+            regNumToIndex[reg.number] = index;
+            indexToReg[index] = reg;
+            offset += reg.spillSlotSize;
+        }
+    }
+
+    /**
+     * Gets the offset of a given register in the CSA.
+     *
+     * @return the offset (in bytes) of {@code reg} in the CSA
+     * @throws IllegalArgumentException if {@code reg} does not have a slot in the CSA
+     */
+    public int offsetOf(int reg) {
+        return indexOf(reg) * slotSize;
+    }
+
+    /**
+     * Gets the index of a given register in the CSA.
+     *
+     * @return the index of {@code reg} in the CSA
+     * @throws IllegalArgumentException if {@code reg} does not have a slot in the CSA
+     */
+    public int indexOf(int reg) {
+        if (!contains(reg)) {
+            throw new IllegalArgumentException(String.valueOf(reg));
+        }
+        return regNumToIndex[reg];
+    }
+
+    /**
+     * Gets the offset of a given register in the CSA.
+     *
+     * @return the offset (in bytes) of {@code reg} in the CSA
+     * @throws IllegalArgumentException if {@code reg} does not have a slot in the CSA
+     */
+    public int offsetOf(CiRegister reg) {
+        return offsetOf(reg.number);
+    }
+
+    /**
+     * Determines if the CSA includes a slot for a given register.
+     *
+     * @param reg the register to test
+     * @return true if the CSA contains a slot for {@code reg}
+     */
+    public boolean contains(int reg) {
+        return reg >= 0 && reg < regNumToIndex.length && regNumToIndex[reg] != -1;
+    }
+
+    /**
+     * Gets the register whose slot in the CSA is at a given index.
+     *
+     * @param index an index of a slot in the CSA
+     * @return the register whose slot in the CSA is at  {@code index} or {@code null} if {@code index} does not denote a
+     *         slot in the CSA aligned with a register
+     */
+    public CiRegister registerAt(int index) {
+        if (index < 0 || index >= indexToReg.length) {
+            return null;
+        }
+        return indexToReg[index];
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder("[");
+        for (CiRegister reg : registers) {
+            if (sb.length() != 1) {
+                sb.append(", ");
+            }
+            sb.append(reg).append("{+").append(offsetOf(reg)).append('}');
+        }
+        return sb.append("] size=").append(size).toString();
+    }
+}