1 /* 2 * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 package jdk.vm.ci.code; 24 25 import static jdk.vm.ci.code.ValueUtil.isAllocatableValue; 26 import static jdk.vm.ci.code.ValueUtil.isStackSlot; 27 import jdk.vm.ci.meta.AllocatableValue; 28 import jdk.vm.ci.meta.Value; 29 30 /** 31 * A calling convention describes the locations in which the arguments for a call are placed and the 32 * location in which the return value is placed if the call is not void. 33 */ 34 public class CallingConvention { 35 36 /** 37 * Marker interface denoting the type of a call for which a calling convention is requested. 38 */ 39 public interface Type { 40 } 41 42 /** 43 * The amount of stack space (in bytes) required for the stack-based arguments of the call. 44 */ 45 private final int stackSize; 46 47 private final AllocatableValue returnLocation; 48 49 /** 50 * The ordered locations in which the arguments are placed. 51 */ 52 private final AllocatableValue[] argumentLocations; 53 54 /** 55 * Creates a description of the registers and stack locations used by a call. 56 * 57 * @param stackSize amount of stack space (in bytes) required for the stack-based arguments of 58 * the call 59 * @param returnLocation the location for the return value or {@link Value#ILLEGAL} if a void 60 * call 61 * @param argumentLocations the ordered locations in which the arguments are placed 62 */ 63 public CallingConvention(int stackSize, AllocatableValue returnLocation, AllocatableValue... argumentLocations) { 64 assert argumentLocations != null; 65 assert returnLocation != null; 66 this.argumentLocations = argumentLocations; 67 this.stackSize = stackSize; 68 this.returnLocation = returnLocation; 69 assert verify(); 70 } 71 72 /** 73 * Gets the location for the return value or {@link Value#ILLEGAL} if a void call. 74 */ 75 public AllocatableValue getReturn() { 76 return returnLocation; 77 } 78 79 /** 80 * Gets the location for the {@code index}'th argument. 81 */ 82 public AllocatableValue getArgument(int index) { 83 return argumentLocations[index]; 84 } 85 86 /** 87 * Gets the amount of stack space (in bytes) required for the stack-based arguments of the call. 88 */ 89 public int getStackSize() { 90 return stackSize; 91 } 92 93 /** 94 * Gets the number of locations required for the arguments. 95 */ 96 public int getArgumentCount() { 97 return argumentLocations.length; 98 } 99 100 /** 101 * Gets the locations required for the arguments. 102 */ 103 public AllocatableValue[] getArguments() { 104 if (argumentLocations.length == 0) { 105 return argumentLocations; 106 } 107 return argumentLocations.clone(); 108 } 109 110 @Override 111 public String toString() { 112 StringBuilder sb = new StringBuilder(); 113 sb.append("CallingConvention["); 114 String sep = ""; 115 for (Value op : argumentLocations) { 116 sb.append(sep).append(op); 117 sep = ", "; 118 } 119 if (!returnLocation.equals(Value.ILLEGAL)) { 120 sb.append(" -> ").append(returnLocation); 121 } 122 sb.append("]"); 123 return sb.toString(); 124 } 125 126 private boolean verify() { 127 for (int i = 0; i < argumentLocations.length; i++) { 128 Value location = argumentLocations[i]; 129 assert isStackSlot(location) || isAllocatableValue(location); 130 } 131 return true; 132 } 133 }