Mercurial > hg > truffle
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(); + } +}