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 * The identifier for this register that is unique across all the registers in a 41 * {@link Architecture}. A valid register has {@code number >= 0}. 42 */ 43 public final int number; 44 45 /** 46 * The mnemonic of this register. 47 */ 48 public final String name; 49 50 /** 51 * The actual encoding in a target machine instruction for this register, which may or may not 52 * be the same as {@link #number}. 53 */ 54 public final int encoding; 55 56 /** 57 * The assembler calls this method to get the register's encoding. 58 */ encoding()59 public int encoding() { 60 return encoding; 61 } 62 63 /** 64 * A platform specific register category that describes which values can be stored in a 65 * register. 66 */ 67 private final RegisterCategory registerCategory; 68 69 /** 70 * A platform specific register type that describes which values can be stored in a register. 71 */ 72 public static class RegisterCategory { 73 74 private final String name; 75 private final boolean mayContainReference; 76 RegisterCategory(String name)77 public RegisterCategory(String name) { 78 this(name, true); 79 } 80 RegisterCategory(String name, boolean mayContainReference)81 public RegisterCategory(String name, boolean mayContainReference) { 82 this.name = name; 83 this.mayContainReference = mayContainReference; 84 } 85 86 @Override toString()87 public String toString() { 88 return name; 89 } 90 91 @Override hashCode()92 public int hashCode() { 93 return 23 + name.hashCode(); 94 } 95 96 @Override equals(Object obj)97 public boolean equals(Object obj) { 98 if (obj instanceof RegisterCategory) { 99 RegisterCategory that = (RegisterCategory) obj; 100 return this.name.equals(that.name); 101 } 102 return false; 103 } 104 } 105 106 /** 107 * Creates a {@link Register} instance. 108 * 109 * @param number unique identifier for the register 110 * @param encoding the target machine encoding for the register 111 * @param name the mnemonic name for the register 112 * @param registerCategory the register category 113 */ Register(int number, int encoding, String name, RegisterCategory registerCategory)114 public Register(int number, int encoding, String name, RegisterCategory registerCategory) { 115 this.number = number; 116 this.name = name; 117 this.registerCategory = registerCategory; 118 this.encoding = encoding; 119 } 120 getRegisterCategory()121 public RegisterCategory getRegisterCategory() { 122 return registerCategory; 123 } 124 125 /** 126 * Determine whether this register needs to be part of the reference map. 127 */ mayContainReference()128 public boolean mayContainReference() { 129 return registerCategory.mayContainReference; 130 } 131 132 /** 133 * Gets this register as a {@linkplain RegisterValue value} with a specified kind. 134 * 135 * @param kind the specified kind 136 * @return the {@link RegisterValue} 137 */ asValue(ValueKind<?> kind)138 public RegisterValue asValue(ValueKind<?> kind) { 139 return new RegisterValue(kind, this); 140 } 141 142 /** 143 * Gets this register as a {@linkplain RegisterValue value} with no particular kind. 144 * 145 * @return a {@link RegisterValue} with {@link ValueKind#Illegal} kind. 146 */ asValue()147 public RegisterValue asValue() { 148 return asValue(ValueKind.Illegal); 149 } 150 151 /** 152 * Determines if this is a valid register. 153 * 154 * @return {@code true} iff this register is valid 155 */ isValid()156 public boolean isValid() { 157 return number >= 0; 158 } 159 160 @Override toString()161 public String toString() { 162 return name; 163 } 164 165 @Override compareTo(Register o)166 public int compareTo(Register o) { 167 if (number < o.number) { 168 return -1; 169 } 170 if (number > o.number) { 171 return 1; 172 } 173 return 0; 174 } 175 176 @Override hashCode()177 public int hashCode() { 178 return 17 + name.hashCode(); 179 } 180 181 @Override equals(Object obj)182 public boolean equals(Object obj) { 183 if (obj instanceof Register) { 184 Register other = (Register) obj; 185 if (number == other.number) { 186 assert name.equals(other.name); 187 assert encoding == other.encoding; 188 assert registerCategory.equals(other.registerCategory); 189 return true; 190 } 191 } 192 return false; 193 } 194 } 195