001/* 002 * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. 008 * 009 * This code is distributed in the hope that it will be useful, but WITHOUT 010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 011 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 012 * version 2 for more details (a copy is included in the LICENSE file that 013 * accompanied this code). 014 * 015 * You should have received a copy of the GNU General Public License version 016 * 2 along with this work; if not, write to the Free Software Foundation, 017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 018 * 019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 020 * or visit www.oracle.com if you need additional information or have any 021 * questions. 022 */ 023package jdk.internal.jvmci.code; 024 025import jdk.internal.jvmci.meta.*; 026 027/** 028 * Represents a target machine register. 029 */ 030public final class Register implements Comparable<Register> { 031 032 public static final RegisterCategory SPECIAL = new RegisterCategory("SPECIAL"); 033 034 /** 035 * Invalid register. 036 */ 037 public static final Register None = new Register(-1, -1, "noreg", SPECIAL); 038 039 /** 040 * Frame pointer of the current method. All spill slots and outgoing stack-based arguments are 041 * addressed relative to this register. 042 */ 043 public static final Register Frame = new Register(-2, -2, "framereg", SPECIAL); 044 045 public static final Register CallerFrame = new Register(-3, -3, "callerframereg", SPECIAL); 046 047 /** 048 * The identifier for this register that is unique across all the registers in a 049 * {@link Architecture}. A valid register has {@code number > 0}. 050 */ 051 public final int number; 052 053 /** 054 * The mnemonic of this register. 055 */ 056 public final String name; 057 058 /** 059 * The actual encoding in a target machine instruction for this register, which may or may not 060 * be the same as {@link #number}. 061 */ 062 public final int encoding; 063 064 /** 065 * The assembler calls this method to get the register's encoding. 066 */ 067 public int encoding() { 068 return encoding; 069 } 070 071 /** 072 * A platform specific register category that describes which values can be stored in a 073 * register. 074 */ 075 private final RegisterCategory registerCategory; 076 077 /** 078 * A platform specific register type that describes which values can be stored in a register. 079 */ 080 public static class RegisterCategory { 081 082 private final String name; 083 084 private final int referenceMapOffset; 085 private final int referenceMapShift; 086 087 public RegisterCategory(String name) { 088 this(name, 0, 0); 089 } 090 091 public RegisterCategory(String name, int referenceMapOffset) { 092 this(name, referenceMapOffset, 0); 093 } 094 095 public RegisterCategory(String name, int referenceMapOffset, int referenceMapShift) { 096 this.name = name; 097 this.referenceMapOffset = referenceMapOffset; 098 this.referenceMapShift = referenceMapShift; 099 } 100 101 @Override 102 public String toString() { 103 return name; 104 } 105 106 @Override 107 public int hashCode() { 108 return 23 + name.hashCode(); 109 } 110 111 @Override 112 public boolean equals(Object obj) { 113 if (obj instanceof RegisterCategory) { 114 RegisterCategory that = (RegisterCategory) obj; 115 return this.referenceMapOffset == that.referenceMapOffset && this.referenceMapShift == that.referenceMapShift && this.name.equals(that.name); 116 } 117 return false; 118 } 119 } 120 121 /** 122 * Creates a {@link Register} instance. 123 * 124 * @param number unique identifier for the register 125 * @param encoding the target machine encoding for the register 126 * @param name the mnemonic name for the register 127 * @param registerCategory the register category 128 */ 129 public Register(int number, int encoding, String name, RegisterCategory registerCategory) { 130 this.number = number; 131 this.name = name; 132 this.registerCategory = registerCategory; 133 this.encoding = encoding; 134 } 135 136 public RegisterCategory getRegisterCategory() { 137 return registerCategory; 138 } 139 140 /** 141 * Get the start index of this register in the {@link ReferenceMap}. 142 */ 143 public int getReferenceMapIndex() { 144 return (encoding << registerCategory.referenceMapShift) + registerCategory.referenceMapOffset; 145 } 146 147 /** 148 * Gets this register as a {@linkplain RegisterValue value} with a specified kind. 149 * 150 * @param kind the specified kind 151 * @return the {@link RegisterValue} 152 */ 153 public RegisterValue asValue(LIRKind kind) { 154 return new RegisterValue(kind, this); 155 } 156 157 /** 158 * Gets this register as a {@linkplain RegisterValue value} with no particular kind. 159 * 160 * @return a {@link RegisterValue} with {@link Kind#Illegal} kind. 161 */ 162 public RegisterValue asValue() { 163 return asValue(LIRKind.Illegal); 164 } 165 166 /** 167 * Determines if this is a valid register. 168 * 169 * @return {@code true} iff this register is valid 170 */ 171 public boolean isValid() { 172 return number >= 0; 173 } 174 175 /** 176 * Gets the maximum register {@linkplain #number number} in a given set of registers. 177 * 178 * @param registers the set of registers to process 179 * @return the maximum register number for any register in {@code registers} 180 */ 181 public static int maxRegisterNumber(Register[] registers) { 182 int max = Integer.MIN_VALUE; 183 for (Register r : registers) { 184 if (r.number > max) { 185 max = r.number; 186 } 187 } 188 return max; 189 } 190 191 /** 192 * Gets the maximum register {@linkplain #encoding encoding} in a given set of registers. 193 * 194 * @param registers the set of registers to process 195 * @return the maximum register encoding for any register in {@code registers} 196 */ 197 public static int maxRegisterEncoding(Register[] registers) { 198 int max = Integer.MIN_VALUE; 199 for (Register r : registers) { 200 if (r.encoding > max) { 201 max = r.encoding; 202 } 203 } 204 return max; 205 } 206 207 @Override 208 public String toString() { 209 return name; 210 } 211 212 @Override 213 public int compareTo(Register o) { 214 if (number < o.number) { 215 return -1; 216 } 217 if (number > o.number) { 218 return 1; 219 } 220 return 0; 221 } 222 223 @Override 224 public int hashCode() { 225 return 17 + name.hashCode(); 226 } 227 228 @Override 229 public boolean equals(Object obj) { 230 if (obj instanceof Register) { 231 Register other = (Register) obj; 232 if (number == other.number) { 233 assert name.equals(other.name); 234 assert encoding == other.encoding; 235 assert registerCategory.equals(other.registerCategory); 236 return true; 237 } 238 } 239 return false; 240 } 241}