1 /* 2 * Copyright (c) 2009, 2015, 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 jdk.vm.ci.meta.JavaKind; 26 import jdk.vm.ci.meta.LIRKind; 27 28 /** 29 * Represents a target machine register. 30 */ 31 public final class Register implements Comparable<Register> { 32 33 public static final RegisterCategory SPECIAL = new RegisterCategory("SPECIAL"); 34 35 /** 36 * Invalid register. 37 */ 38 public static final Register None = new Register(-1, -1, "noreg", SPECIAL); 39 40 /** 41 * Frame pointer of the current method. All spill slots and outgoing stack-based arguments are 42 * addressed relative to this register. 43 */ 44 public static final Register Frame = new Register(-2, -2, "framereg", SPECIAL); 45 46 public static final Register CallerFrame = new Register(-3, -3, "callerframereg", SPECIAL); 47 48 /** 49 * The identifier for this register that is unique across all the registers in a 50 * {@link Architecture}. A valid register has {@code number > 0}. 51 */ 52 public final int number; 53 54 /** 55 * The mnemonic of this register. 56 */ 57 public final String name; 58 59 /** 60 * The actual encoding in a target machine instruction for this register, which may or may not 61 * be the same as {@link #number}. 62 */ 63 public final int encoding; 64 65 /** 66 * The assembler calls this method to get the register's encoding. 67 */ 68 public int encoding() { 69 return encoding; 70 } 71 72 /** 73 * A platform specific register category that describes which values can be stored in a 74 * register. 75 */ 76 private final RegisterCategory registerCategory; 77 78 /** 79 * A platform specific register type that describes which values can be stored in a register. 80 */ 81 public static class RegisterCategory { 82 83 private final String name; 84 private final boolean mayContainReference; 85 86 public RegisterCategory(String name) { 87 this(name, true); 88 } 89 90 public RegisterCategory(String name, boolean mayContainReference) { 91 this.name = name; 92 this.mayContainReference = mayContainReference; 93 } 94 95 @Override 96 public String toString() { 97 return name; 98 } 99 100 @Override 101 public int hashCode() { 102 return 23 + name.hashCode(); 103 } 104 105 @Override 106 public boolean equals(Object obj) { 107 if (obj instanceof RegisterCategory) { 108 RegisterCategory that = (RegisterCategory) obj; 109 return this.name.equals(that.name); 110 } 111 return false; 112 } 113 } 114 115 /** 116 * Creates a {@link Register} instance. 117 * 118 * @param number unique identifier for the register 119 * @param encoding the target machine encoding for the register 120 * @param name the mnemonic name for the register 121 * @param registerCategory the register category 122 */ 123 public Register(int number, int encoding, String name, RegisterCategory registerCategory) { 124 this.number = number; 125 this.name = name; 126 this.registerCategory = registerCategory; 127 this.encoding = encoding; 128 } 129 130 public RegisterCategory getRegisterCategory() { 131 return registerCategory; 132 } 133 134 /** 135 * Determine whether this register needs to be part of the reference map. 136 */ 137 public boolean mayContainReference() { 138 return registerCategory.mayContainReference; 139 } 140 141 /** 142 * Gets this register as a {@linkplain RegisterValue value} with a specified kind. 143 * 144 * @param kind the specified kind 145 * @return the {@link RegisterValue} 146 */ 147 public RegisterValue asValue(LIRKind kind) { 148 return new RegisterValue(kind, this); 149 } 150 151 /** 152 * Gets this register as a {@linkplain RegisterValue value} with no particular kind. 153 * 154 * @return a {@link RegisterValue} with {@link JavaKind#Illegal} kind. 155 */ 156 public RegisterValue asValue() { 157 return asValue(LIRKind.Illegal); 158 } 159 160 /** 161 * Determines if this is a valid register. 162 * 163 * @return {@code true} iff this register is valid 164 */ 165 public boolean isValid() { 166 return number >= 0; 167 } 168 169 /** 170 * Gets the maximum register {@linkplain #number number} in a given set of registers. 171 * 172 * @param registers the set of registers to process 173 * @return the maximum register number for any register in {@code registers} 174 */ 175 public static int maxRegisterNumber(Register[] registers) { 176 int max = Integer.MIN_VALUE; 177 for (Register r : registers) { 178 if (r.number > max) { 179 max = r.number; 180 } 181 } 182 return max; 183 } 184 185 /** 186 * Gets the maximum register {@linkplain #encoding encoding} in a given set of registers. 187 * 188 * @param registers the set of registers to process 189 * @return the maximum register encoding for any register in {@code registers} 190 */ 191 public static int maxRegisterEncoding(Register[] registers) { 192 int max = Integer.MIN_VALUE; 193 for (Register r : registers) { 194 if (r.encoding > max) { 195 max = r.encoding; 196 } 197 } 198 return max; 199 } 200 201 @Override 202 public String toString() { 203 return name; 204 } 205 206 @Override 207 public int compareTo(Register o) { 208 if (number < o.number) { 209 return -1; 210 } 211 if (number > o.number) { 212 return 1; 213 } 214 return 0; 215 } 216 217 @Override 218 public int hashCode() { 219 return 17 + name.hashCode(); 220 } 221 222 @Override 223 public boolean equals(Object obj) { 224 if (obj instanceof Register) { 225 Register other = (Register) obj; 226 if (number == other.number) { 227 assert name.equals(other.name); 228 assert encoding == other.encoding; 229 assert registerCategory.equals(other.registerCategory); 230 return true; 231 } 232 } 233 return false; 234 } 235 }