register.hpp revision 6412:53a41e7cbe05
1208737Sjmallett/* 2208737Sjmallett * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. 3208737Sjmallett * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4208737Sjmallett * 5208737Sjmallett * This code is free software; you can redistribute it and/or modify it 6208737Sjmallett * under the terms of the GNU General Public License version 2 only, as 7208737Sjmallett * published by the Free Software Foundation. 8208737Sjmallett * 9208737Sjmallett * This code is distributed in the hope that it will be useful, but WITHOUT 10208737Sjmallett * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11208737Sjmallett * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12208737Sjmallett * version 2 for more details (a copy is included in the LICENSE file that 13208737Sjmallett * accompanied this code). 14208737Sjmallett * 15208737Sjmallett * You should have received a copy of the GNU General Public License version 16208737Sjmallett * 2 along with this work; if not, write to the Free Software Foundation, 17208737Sjmallett * 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 */ 24 25#ifndef SHARE_VM_ASM_REGISTER_HPP 26#define SHARE_VM_ASM_REGISTER_HPP 27 28#include "utilities/top.hpp" 29 30// Use AbstractRegister as shortcut 31class AbstractRegisterImpl; 32typedef AbstractRegisterImpl* AbstractRegister; 33 34 35// The super class for platform specific registers. Instead of using value objects, 36// registers are implemented as pointers. Subclassing is used so all registers can 37// use the debugging suport below. No virtual functions are used for efficiency. 38// They are canonicalized; i.e., registers are equal if their pointers are equal, 39// and vice versa. A concrete implementation may just map the register onto 'this'. 40 41class AbstractRegisterImpl { 42 protected: 43 int value() const { return (int)(intx)this; } 44}; 45 46 47// 48// Macros for use in defining Register instances. We'd like to be 49// able to simply define const instances of the RegisterImpl* for each 50// of the registers needed on a system in a header file. However many 51// compilers don't handle this very well and end up producing a 52// private definition in every file which includes the header file. 53// Along with the static constructors necessary for initialization it 54// can consume a significant amount of space in the result library. 55// 56// The following macros allow us to declare the instance in a .hpp and 57// produce an enumeration value which has the same number. Then in a 58// .cpp the the register instance can be defined using the enumeration 59// value. This avoids the use of static constructors and multiple 60// definitions per .cpp. In addition #defines for the register can be 61// produced so that the constant registers can be inlined. These 62// macros should not be used inside other macros, because you may get 63// multiple evaluations of the macros which can give bad results. 64// 65// Here are some example uses and expansions. Note that the macro 66// invocation is terminated with a ;. 67// 68// CONSTANT_REGISTER_DECLARATION(Register, G0, 0); 69// 70// extern const Register G0 ; 71// enum { G0_RegisterEnumValue = 0 } ; 72// 73// REGISTER_DECLARATION(Register, Gmethod, G5); 74// 75// extern const Register Gmethod ; 76// enum { Gmethod_RegisterEnumValue = G5_RegisterEnumValue } ; 77// 78// REGISTER_DEFINITION(Register, G0); 79// 80// const Register G0 = ( ( Register ) G0_RegisterEnumValue ) ; 81// 82 83#define AS_REGISTER(type,name) ((type)name##_##type##EnumValue) 84 85#define CONSTANT_REGISTER_DECLARATION(type, name, value) \ 86extern const type name; \ 87enum { name##_##type##EnumValue = (value) } 88 89#define REGISTER_DECLARATION(type, name, value) \ 90extern const type name; \ 91enum { name##_##type##EnumValue = value##_##type##EnumValue } 92 93#define REGISTER_DEFINITION(type, name) \ 94const type name = ((type)name##_##type##EnumValue) 95 96#ifdef TARGET_ARCH_x86 97# include "register_x86.hpp" 98#endif 99#ifdef TARGET_ARCH_sparc 100# include "register_sparc.hpp" 101#endif 102#ifdef TARGET_ARCH_zero 103# include "register_zero.hpp" 104#endif 105#ifdef TARGET_ARCH_arm 106# include "register_arm.hpp" 107#endif 108#ifdef TARGET_ARCH_ppc 109# include "register_ppc.hpp" 110#endif 111 112 113// Debugging support 114 115inline void assert_different_registers( 116 AbstractRegister a, 117 AbstractRegister b 118) { 119 assert( 120 a != b, 121 err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT "", 122 p2i(a), p2i(b)) 123 ); 124} 125 126 127inline void assert_different_registers( 128 AbstractRegister a, 129 AbstractRegister b, 130 AbstractRegister c 131) { 132 assert( 133 a != b && a != c 134 && b != c, 135 err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT 136 ", c=" INTPTR_FORMAT "", 137 p2i(a), p2i(b), p2i(c)) 138 ); 139} 140 141 142inline void assert_different_registers( 143 AbstractRegister a, 144 AbstractRegister b, 145 AbstractRegister c, 146 AbstractRegister d 147) { 148 assert( 149 a != b && a != c && a != d 150 && b != c && b != d 151 && c != d, 152 err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT 153 ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT "", 154 p2i(a), p2i(b), p2i(c), p2i(d)) 155 ); 156} 157 158 159inline void assert_different_registers( 160 AbstractRegister a, 161 AbstractRegister b, 162 AbstractRegister c, 163 AbstractRegister d, 164 AbstractRegister e 165) { 166 assert( 167 a != b && a != c && a != d && a != e 168 && b != c && b != d && b != e 169 && c != d && c != e 170 && d != e, 171 err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT 172 ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT "", 173 p2i(a), p2i(b), p2i(c), p2i(d), p2i(e)) 174 ); 175} 176 177 178inline void assert_different_registers( 179 AbstractRegister a, 180 AbstractRegister b, 181 AbstractRegister c, 182 AbstractRegister d, 183 AbstractRegister e, 184 AbstractRegister f 185) { 186 assert( 187 a != b && a != c && a != d && a != e && a != f 188 && b != c && b != d && b != e && b != f 189 && c != d && c != e && c != f 190 && d != e && d != f 191 && e != f, 192 err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT 193 ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT 194 ", f=" INTPTR_FORMAT "", 195 p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f)) 196 ); 197} 198 199 200inline void assert_different_registers( 201 AbstractRegister a, 202 AbstractRegister b, 203 AbstractRegister c, 204 AbstractRegister d, 205 AbstractRegister e, 206 AbstractRegister f, 207 AbstractRegister g 208) { 209 assert( 210 a != b && a != c && a != d && a != e && a != f && a != g 211 && b != c && b != d && b != e && b != f && b != g 212 && c != d && c != e && c != f && c != g 213 && d != e && d != f && d != g 214 && e != f && e != g 215 && f != g, 216 err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT 217 ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT 218 ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT "", 219 p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g)) 220 ); 221} 222 223 224inline void assert_different_registers( 225 AbstractRegister a, 226 AbstractRegister b, 227 AbstractRegister c, 228 AbstractRegister d, 229 AbstractRegister e, 230 AbstractRegister f, 231 AbstractRegister g, 232 AbstractRegister h 233) { 234 assert( 235 a != b && a != c && a != d && a != e && a != f && a != g && a != h 236 && b != c && b != d && b != e && b != f && b != g && b != h 237 && c != d && c != e && c != f && c != g && c != h 238 && d != e && d != f && d != g && d != h 239 && e != f && e != g && e != h 240 && f != g && f != h 241 && g != h, 242 err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT 243 ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT 244 ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT "", 245 p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h)) 246 ); 247} 248 249 250inline void assert_different_registers( 251 AbstractRegister a, 252 AbstractRegister b, 253 AbstractRegister c, 254 AbstractRegister d, 255 AbstractRegister e, 256 AbstractRegister f, 257 AbstractRegister g, 258 AbstractRegister h, 259 AbstractRegister i 260) { 261 assert( 262 a != b && a != c && a != d && a != e && a != f && a != g && a != h && a != i 263 && b != c && b != d && b != e && b != f && b != g && b != h && b != i 264 && c != d && c != e && c != f && c != g && c != h && c != i 265 && d != e && d != f && d != g && d != h && d != i 266 && e != f && e != g && e != h && e != i 267 && f != g && f != h && f != i 268 && g != h && g != i 269 && h != i, 270 err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT 271 ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT 272 ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT 273 ", i=" INTPTR_FORMAT "", 274 p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i)) 275 ); 276} 277 278#endif // SHARE_VM_ASM_REGISTER_HPP 279