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