blob: 1c839e9ba54af0784f14ae7f1c3839bfb3474664 [file] [log] [blame]
/*
* Copyright (c) 2009, 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 jdk.vm.ci.code;
import static jdk.vm.ci.code.ValueUtil.isAllocatableValue;
import static jdk.vm.ci.code.ValueUtil.isStackSlot;
import jdk.vm.ci.meta.AllocatableValue;
import jdk.vm.ci.meta.Value;
/**
* A calling convention describes the locations in which the arguments for a call are placed and the
* location in which the return value is placed if the call is not void.
*/
public class CallingConvention {
/**
* Marker interface denoting the type of a call for which a calling convention is requested.
*/
public interface Type {
}
/**
* The amount of stack space (in bytes) required for the stack-based arguments of the call.
*/
private final int stackSize;
private final AllocatableValue returnLocation;
/**
* The ordered locations in which the arguments are placed.
*/
private final AllocatableValue[] argumentLocations;
/**
* Creates a description of the registers and stack locations used by a call.
*
* @param stackSize amount of stack space (in bytes) required for the stack-based arguments of
* the call
* @param returnLocation the location for the return value or {@link Value#ILLEGAL} if a void
* call
* @param argumentLocations the ordered locations in which the arguments are placed
*/
public CallingConvention(int stackSize, AllocatableValue returnLocation, AllocatableValue... argumentLocations) {
assert argumentLocations != null;
assert returnLocation != null;
this.argumentLocations = argumentLocations;
this.stackSize = stackSize;
this.returnLocation = returnLocation;
assert verify();
}
/**
* Gets the location for the return value or {@link Value#ILLEGAL} if a void call.
*/
public AllocatableValue getReturn() {
return returnLocation;
}
/**
* Gets the location for the {@code index}'th argument.
*/
public AllocatableValue getArgument(int index) {
return argumentLocations[index];
}
/**
* Gets the amount of stack space (in bytes) required for the stack-based arguments of the call.
*/
public int getStackSize() {
return stackSize;
}
/**
* Gets the number of locations required for the arguments.
*/
public int getArgumentCount() {
return argumentLocations.length;
}
/**
* Gets the locations required for the arguments.
*/
@SuppressFBWarnings(value = "EI_EXPOSE_REP", justification = "FB false positive")
public AllocatableValue[] getArguments() {
if (argumentLocations.length == 0) {
return argumentLocations;
}
return argumentLocations.clone();
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("CallingConvention[");
String sep = "";
for (Value op : argumentLocations) {
sb.append(sep).append(op);
sep = ", ";
}
if (!returnLocation.equals(Value.ILLEGAL)) {
sb.append(" -> ").append(returnLocation);
}
sb.append("]");
return sb.toString();
}
private boolean verify() {
for (int i = 0; i < argumentLocations.length; i++) {
Value location = argumentLocations[i];
assert isStackSlot(location) || isAllocatableValue(location);
}
return true;
}
}