1 2 /* 3 * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 */ 24 package jdk.vm.ci.code; 25 26 import jdk.vm.ci.meta.JavaKind; 27 import jdk.vm.ci.meta.LIRKind; 28 29 /** 30 * Represents a target machine register. 31 */ 32 public final class Register implements Comparable<Register> { 33 34 public static final RegisterCategory SPECIAL = new RegisterCategory("SPECIAL"); 35 36 /** 37 * Invalid register. 38 */ 39 public static final Register None = new Register(-1, -1, "noreg", SPECIAL); 40 41 /** 42 * Frame pointer of the current method. All spill slots and outgoing stack-based arguments are 43 * addressed relative to this register. 44 */ 45 public static final Register Frame = new Register(-2, -2, "framereg", SPECIAL); 46 47 public static final Register CallerFrame = new Register(-3, -3, "callerframereg", SPECIAL); 48 49 /** 50 * The identifier for this register that is unique across all the registers in a 51 * {@link Architecture}. A valid register has {@code number > 0}. 52 */ 53 public final int number; 54 55 /** 56 * The mnemonic of this register. 57 */ 58 public final String name; 59 60 /** 61 * The actual encoding in a target machine instruction for this register, which may or may not 62 * be the same as {@link #number}. 63 */ 64 public final int encoding; 65 66 /** 67 * The assembler calls this method to get the register's encoding. 68 */ 69 public int encoding() { 70 return encoding; 71 } 72 73 /** 74 * A platform specific register category that describes which values can be stored in a 75 * register. 76 */ 77 private final RegisterCategory registerCategory; 78 79 /** 80 * A platform specific register type that describes which values can be stored in a register. 81 */ 82 public static class RegisterCategory { 83 84 private final String name; 85 private final boolean mayContainReference; 86 87 public RegisterCategory(String name) { 88 this(name, true); 89 } 90 91 public RegisterCategory(String name, boolean mayContainReference) { 92 this.name = name; 93 this.mayContainReference = mayContainReference; 94 } 95 96 @Override 97 public String toString() { 98 return name; 99 } 100 101 @Override 102 public int hashCode() { 103 return 23 + name.hashCode(); 104 } 105 106 @Override 107 public boolean equals(Object obj) { 108 if (obj instanceof RegisterCategory) { 109 RegisterCategory that = (RegisterCategory) obj; 110 return this.name.equals(that.name); 111 } 112 return false; 113 } 114 } 115 116 /** 117 * Creates a {@link Register} instance. 118 * 119 * @param number unique identifier for the register 120 * @param encoding the target machine encoding for the register 121 * @param name the mnemonic name for the register 122 * @param registerCategory the register category 123 */ 124 public Register(int number, int encoding, String name, RegisterCategory registerCategory) { 125 this.number = number; 126 this.name = name; 127 this.registerCategory = registerCategory; 128 this.encoding = encoding; 129 } 130 131 public RegisterCategory getRegisterCategory() { 132 return registerCategory; 133 } 134 135 /** 136 * Determine whether this register needs to be part of the reference map. 137 */ 138 public boolean mayContainReference() { 139 return registerCategory.mayContainReference; 140 } 141 142 /** 143 * Gets this register as a {@linkplain RegisterValue value} with a specified kind. 144 * 145 * @param kind the specified kind 146 * @return the {@link RegisterValue} 147 */ 148 public RegisterValue asValue(LIRKind kind) { 149 return new RegisterValue(kind, this); 150 } 151 152 /** 153 * Gets this register as a {@linkplain RegisterValue value} with no particular kind. 154 * 155 * @return a {@link RegisterValue} with {@link JavaKind#Illegal} kind. 156 */ 157 public RegisterValue asValue() { 158 return asValue(LIRKind.Illegal); 159 } 160 161 /** 162 * Determines if this is a valid register. 163 * 164 * @return {@code true} iff this register is valid 165 */ 166 public boolean isValid() { 167 return number >= 0; 168 } 169 170 /** 171 * Gets the maximum register {@linkplain #number number} in a given set of registers. 172 * 173 * @param registers the set of registers to process 174 * @return the maximum register number for any register in {@code registers} 175 */ 176 public static int maxRegisterNumber(Register[] registers) { 177 int max = Integer.MIN_VALUE; 178 for (Register r : registers) { 179 if (r.number > max) { 180 max = r.number; 181 } 182 } 183 return max; 184 } 185 186 /** 187 * Gets the maximum register {@linkplain #encoding encoding} in a given set of registers. 188 * 189 * @param registers the set of registers to process 190 * @return the maximum register encoding for any register in {@code registers} 191 */ 192 public static int maxRegisterEncoding(Register[] registers) { 193 int max = Integer.MIN_VALUE; 194 for (Register r : registers) { 195 if (r.encoding > max) { 196 max = r.encoding; 197 } 198 } 199 return max; 200 } 201 202 @Override 203 public String toString() { 204 return name; 205 } 206 207 @Override 208 public int compareTo(Register o) { 209 if (number < o.number) { 210 return -1; 211 } 212 if (number > o.number) { 213 return 1; 214 } 215 return 0; 216 } 217 218 @Override 219 public int hashCode() { 220 return 17 + name.hashCode(); 221 } 222 223 @Override 224 public boolean equals(Object obj) { 225 if (obj instanceof Register) { 226 Register other = (Register) obj; 227 if (number == other.number) { 228 assert name.equals(other.name); 229 assert encoding == other.encoding; 230 assert registerCategory.equals(other.registerCategory); 231 return true; 232 } 233 } 234 return false; 235 } 236 }