duke@435: /* duke@435: * Copyright 2000-2002 Sun Microsystems, Inc. All Rights Reserved. duke@435: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@435: * duke@435: * This code is free software; you can redistribute it and/or modify it duke@435: * under the terms of the GNU General Public License version 2 only, as duke@435: * published by the Free Software Foundation. duke@435: * duke@435: * This code is distributed in the hope that it will be useful, but WITHOUT duke@435: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@435: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@435: * version 2 for more details (a copy is included in the LICENSE file that duke@435: * accompanied this code). duke@435: * duke@435: * You should have received a copy of the GNU General Public License version duke@435: * 2 along with this work; if not, write to the Free Software Foundation, duke@435: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@435: * duke@435: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, duke@435: * CA 95054 USA or visit www.sun.com if you need additional information or duke@435: * have any questions. duke@435: * duke@435: */ duke@435: duke@435: // Use AbstractRegister as shortcut duke@435: class AbstractRegisterImpl; duke@435: typedef AbstractRegisterImpl* AbstractRegister; duke@435: duke@435: duke@435: // The super class for platform specific registers. Instead of using value objects, duke@435: // registers are implemented as pointers. Subclassing is used so all registers can duke@435: // use the debugging suport below. No virtual functions are used for efficiency. duke@435: // They are canonicalized; i.e., registers are equal if their pointers are equal, duke@435: // and vice versa. A concrete implementation may just map the register onto 'this'. duke@435: duke@435: class AbstractRegisterImpl { duke@435: protected: duke@435: int value() const { return (int)(intx)this; } duke@435: }; duke@435: duke@435: duke@435: // duke@435: // Macros for use in defining Register instances. We'd like to be duke@435: // able to simply define const instances of the RegisterImpl* for each duke@435: // of the registers needed on a system in a header file. However many duke@435: // compilers don't handle this very well and end up producing a duke@435: // private definition in every file which includes the header file. duke@435: // Along with the static constructors necessary for initialization it duke@435: // can consume a significant amount of space in the result library. duke@435: // duke@435: // The following macros allow us to declare the instance in a .hpp and duke@435: // produce an enumeration value which has the same number. Then in a duke@435: // .cpp the the register instance can be defined using the enumeration duke@435: // value. This avoids the use of static constructors and multiple duke@435: // definitions per .cpp. In addition #defines for the register can be duke@435: // produced so that the constant registers can be inlined. These duke@435: // macros should not be used inside other macros, because you may get duke@435: // multiple evaluations of the macros which can give bad results. duke@435: // duke@435: // Here are some example uses and expansions. Note that the macro duke@435: // invocation is terminated with a ;. duke@435: // duke@435: // CONSTANT_REGISTER_DECLARATION(Register, G0, 0); duke@435: // duke@435: // extern const Register G0 ; duke@435: // enum { G0_RegisterEnumValue = 0 } ; duke@435: // duke@435: // REGISTER_DECLARATION(Register, Gmethod, G5); duke@435: // duke@435: // extern const Register Gmethod ; duke@435: // enum { Gmethod_RegisterEnumValue = G5_RegisterEnumValue } ; duke@435: // duke@435: // REGISTER_DEFINITION(Register, G0); duke@435: // duke@435: // const Register G0 = ( ( Register ) G0_RegisterEnumValue ) ; duke@435: // duke@435: duke@435: #define AS_REGISTER(type,name) ((type)name##_##type##EnumValue) duke@435: duke@435: #define CONSTANT_REGISTER_DECLARATION(type, name, value) \ duke@435: extern const type name; \ duke@435: enum { name##_##type##EnumValue = (value) } duke@435: duke@435: #define REGISTER_DECLARATION(type, name, value) \ duke@435: extern const type name; \ duke@435: enum { name##_##type##EnumValue = value##_##type##EnumValue } duke@435: duke@435: #define REGISTER_DEFINITION(type, name) \ duke@435: const type name = ((type)name##_##type##EnumValue) duke@435: duke@435: duke@435: duke@435: // Debugging support duke@435: duke@435: inline void assert_different_registers( duke@435: AbstractRegister a, duke@435: AbstractRegister b duke@435: ) { duke@435: assert( duke@435: a != b, duke@435: "registers must be different" duke@435: ); duke@435: } duke@435: duke@435: duke@435: inline void assert_different_registers( duke@435: AbstractRegister a, duke@435: AbstractRegister b, duke@435: AbstractRegister c duke@435: ) { duke@435: assert( duke@435: a != b && a != c duke@435: && b != c, duke@435: "registers must be different" duke@435: ); duke@435: } duke@435: duke@435: duke@435: inline void assert_different_registers( duke@435: AbstractRegister a, duke@435: AbstractRegister b, duke@435: AbstractRegister c, duke@435: AbstractRegister d duke@435: ) { duke@435: assert( duke@435: a != b && a != c && a != d duke@435: && b != c && b != d duke@435: && c != d, duke@435: "registers must be different" duke@435: ); duke@435: } duke@435: duke@435: duke@435: inline void assert_different_registers( duke@435: AbstractRegister a, duke@435: AbstractRegister b, duke@435: AbstractRegister c, duke@435: AbstractRegister d, duke@435: AbstractRegister e duke@435: ) { duke@435: assert( duke@435: a != b && a != c && a != d && a != e duke@435: && b != c && b != d && b != e duke@435: && c != d && c != e duke@435: && d != e, duke@435: "registers must be different" duke@435: ); duke@435: } duke@435: duke@435: duke@435: inline void assert_different_registers( duke@435: AbstractRegister a, duke@435: AbstractRegister b, duke@435: AbstractRegister c, duke@435: AbstractRegister d, duke@435: AbstractRegister e, duke@435: AbstractRegister f duke@435: ) { duke@435: assert( duke@435: a != b && a != c && a != d && a != e && a != f duke@435: && b != c && b != d && b != e && b != f duke@435: && c != d && c != e && c != f duke@435: && d != e && d != f duke@435: && e != f, duke@435: "registers must be different" duke@435: ); duke@435: } duke@435: duke@435: duke@435: inline void assert_different_registers( duke@435: AbstractRegister a, duke@435: AbstractRegister b, duke@435: AbstractRegister c, duke@435: AbstractRegister d, duke@435: AbstractRegister e, duke@435: AbstractRegister f, duke@435: AbstractRegister g duke@435: ) { duke@435: assert( duke@435: a != b && a != c && a != d && a != e && a != f && a != g duke@435: && b != c && b != d && b != e && b != f && b != g duke@435: && c != d && c != e && c != f && c != g duke@435: && d != e && d != f && d != g duke@435: && e != f && e != g duke@435: && f != g, duke@435: "registers must be different" duke@435: ); duke@435: } duke@435: duke@435: duke@435: inline void assert_different_registers( duke@435: AbstractRegister a, duke@435: AbstractRegister b, duke@435: AbstractRegister c, duke@435: AbstractRegister d, duke@435: AbstractRegister e, duke@435: AbstractRegister f, duke@435: AbstractRegister g, duke@435: AbstractRegister h duke@435: ) { duke@435: assert( duke@435: a != b && a != c && a != d && a != e && a != f && a != g && a != h duke@435: && b != c && b != d && b != e && b != f && b != g && b != h duke@435: && c != d && c != e && c != f && c != g && c != h duke@435: && d != e && d != f && d != g && d != h duke@435: && e != f && e != g && e != h duke@435: && f != g && f != h duke@435: && g != h, duke@435: "registers must be different" duke@435: ); duke@435: }