register.hpp revision 11658:8a5735c11a84
14910Swollman/*
24910Swollman * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
34910Swollman * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44910Swollman *
530300Sjoerg * This code is free software; you can redistribute it and/or modify it
625944Sjoerg * under the terms of the GNU General Public License version 2 only, as
74910Swollman * published by the Free Software Foundation.
825944Sjoerg *
988534Sjoerg * This code is distributed in the hope that it will be useful, but WITHOUT
1025944Sjoerg * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
114910Swollman * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
124910Swollman * version 2 for more details (a copy is included in the LICENSE file that
134910Swollman * accompanied this code).
144910Swollman *
154910Swollman * You should have received a copy of the GNU General Public License version
164910Swollman * 2 along with this work; if not, write to the Free Software Foundation,
174910Swollman * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1830300Sjoerg *
1916288Sgpalmer * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2050477Speter * or visit www.oracle.com if you need additional information or have any
214910Swollman * questions.
224910Swollman *
2340008Sjoerg */
2440008Sjoerg
2542065Sphk#ifndef SHARE_VM_ASM_REGISTER_HPP
2632350Seivind#define SHARE_VM_ASM_REGISTER_HPP
2754263Sshin
2831742Seivind#include "utilities/debug.hpp"
2940008Sjoerg#include "utilities/globalDefinitions.hpp"
3031742Seivind#include "utilities/macros.hpp"
3140008Sjoerg
3240008Sjoerg// Use AbstractRegister as shortcut
3340008Sjoergclass AbstractRegisterImpl;
3454263Sshintypedef AbstractRegisterImpl* AbstractRegister;
3540008Sjoerg
3640008Sjoerg
3740008Sjoerg// The super class for platform specific registers. Instead of using value objects,
3840008Sjoerg// registers are implemented as pointers. Subclassing is used so all registers can
394952Sbde// use the debugging suport below. No virtual functions are used for efficiency.
404952Sbde// They are canonicalized; i.e., registers are equal if their pointers are equal,
4170199Sjhay// and vice versa. A concrete implementation may just map the register onto 'this'.
4224204Sbde
434910Swollmanclass AbstractRegisterImpl {
4425706Sjoerg protected:
4542104Sphk  int value() const                              { return (int)(intx)this; }
4659604Sobrien};
4742104Sphk
4829024Sbde
494910Swollman//
5040008Sjoerg// Macros for use in defining Register instances.  We'd like to be
5140008Sjoerg// able to simply define const instances of the RegisterImpl* for each
5240008Sjoerg// of the registers needed on a system in a header file.  However many
5340008Sjoerg// compilers don't handle this very well and end up producing a
5430300Sjoerg// private definition in every file which includes the header file.
5540008Sjoerg// Along with the static constructors necessary for initialization it
564910Swollman// can consume a significant amount of space in the result library.
574910Swollman//
584910Swollman// The following macros allow us to declare the instance in a .hpp and
594910Swollman// produce an enumeration value which has the same number.  Then in a
6042104Sphk// .cpp the the register instance can be defined using the enumeration
6188534Sjoerg// value.  This avoids the use of static constructors and multiple
6288534Sjoerg// definitions per .cpp.  In addition #defines for the register can be
6388534Sjoerg// produced so that the constant registers can be inlined.  These
6488534Sjoerg// macros should not be used inside other macros, because you may get
654910Swollman// multiple evaluations of the macros which can give bad results.
6640008Sjoerg//
6740008Sjoerg// Here are some example uses and expansions.  Note that the macro
6840008Sjoerg// invocation is terminated with a ;.
6942104Sphk//
7030300Sjoerg// CONSTANT_REGISTER_DECLARATION(Register, G0, 0);
7130300Sjoerg//
724910Swollman// extern const Register G0 ;
734910Swollman// enum { G0_RegisterEnumValue = 0 } ;
744910Swollman//
754910Swollman// REGISTER_DECLARATION(Register, Gmethod, G5);
764910Swollman//
774910Swollman// extern const Register Gmethod ;
7840008Sjoerg// enum { Gmethod_RegisterEnumValue = G5_RegisterEnumValue } ;
7940008Sjoerg//
8040008Sjoerg// REGISTER_DEFINITION(Register, G0);
8140008Sjoerg//
8240008Sjoerg// const Register G0 = ( ( Register ) G0_RegisterEnumValue ) ;
8332350Seivind//
8440008Sjoerg
854910Swollman#define AS_REGISTER(type,name)         ((type)name##_##type##EnumValue)
864910Swollman
8711819Sjulian#define CONSTANT_REGISTER_DECLARATION(type, name, value) \
8811819Sjulianextern const type name;                                  \
8911819Sjulianenum { name##_##type##EnumValue = (value) }
9011819Sjulian
9111819Sjulian#define REGISTER_DECLARATION(type, name, value) \
924910Swollmanextern const type name;                         \
934910Swollmanenum { name##_##type##EnumValue = value##_##type##EnumValue }
944910Swollman
954910Swollman#define REGISTER_DEFINITION(type, name) \
964910Swollmanconst type name = ((type)name##_##type##EnumValue)
974910Swollman
984910Swollman#include CPU_HEADER(register)
9942065Sphk
10042064Sphk// Debugging support
10142064Sphk
10242104Sphkinline void assert_different_registers(
10340008Sjoerg  AbstractRegister a,
10442064Sphk  AbstractRegister b
10542064Sphk) {
10642104Sphk  assert(
10740008Sjoerg    a != b,
10842104Sphk    "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT "", p2i(a), p2i(b)
1094910Swollman  );
1104910Swollman}
11125944Sjoerg
11225944Sjoerg
11325944Sjoerginline void assert_different_registers(
11425955Sjoerg  AbstractRegister a,
11525944Sjoerg  AbstractRegister b,
11625944Sjoerg  AbstractRegister c
11725944Sjoerg) {
11825955Sjoerg  assert(
11925955Sjoerg    a != b && a != c
12025955Sjoerg           && b != c,
12130300Sjoerg    "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
12230300Sjoerg    ", c=" INTPTR_FORMAT "",
12330300Sjoerg    p2i(a), p2i(b), p2i(c)
12430300Sjoerg  );
12530300Sjoerg}
12630300Sjoerg
12730300Sjoerg
12830300Sjoerginline void assert_different_registers(
12930300Sjoerg  AbstractRegister a,
13025944Sjoerg  AbstractRegister b,
13125944Sjoerg  AbstractRegister c,
13225955Sjoerg  AbstractRegister d
13325955Sjoerg) {
13445152Sphk  assert(
13525944Sjoerg    a != b && a != c && a != d
13630300Sjoerg           && b != c && b != d
13730300Sjoerg                     && c != d,
13830300Sjoerg    "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
13930300Sjoerg    ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT "",
14030300Sjoerg    p2i(a), p2i(b), p2i(c), p2i(d)
14130300Sjoerg  );
14288534Sjoerg}
14388534Sjoerg
14478064Sume
14530300Sjoerginline void assert_different_registers(
14630300Sjoerg  AbstractRegister a,
14730300Sjoerg  AbstractRegister b,
14830300Sjoerg  AbstractRegister c,
14978064Sume  AbstractRegister d,
1504910Swollman  AbstractRegister e
15125944Sjoerg) {
15225944Sjoerg  assert(
15325944Sjoerg    a != b && a != c && a != d && a != e
15425944Sjoerg           && b != c && b != d && b != e
15525944Sjoerg                     && c != d && c != e
15625944Sjoerg                               && d != e,
15725944Sjoerg    "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
15825944Sjoerg    ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT "",
15925944Sjoerg    p2i(a), p2i(b), p2i(c), p2i(d), p2i(e)
16025944Sjoerg  );
16125944Sjoerg}
1624910Swollman
16330300Sjoerg
16430300Sjoerginline void assert_different_registers(
16530300Sjoerg  AbstractRegister a,
16630300Sjoerg  AbstractRegister b,
16730300Sjoerg  AbstractRegister c,
16830300Sjoerg  AbstractRegister d,
16930300Sjoerg  AbstractRegister e,
17030300Sjoerg  AbstractRegister f
1714910Swollman) {
17225944Sjoerg  assert(
17325944Sjoerg    a != b && a != c && a != d && a != e && a != f
17425944Sjoerg           && b != c && b != d && b != e && b != f
1754910Swollman                     && c != d && c != e && c != f
17678064Sume                               && d != e && d != f
17778064Sume                                         && e != f,
17878064Sume    "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
17988534Sjoerg    ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
18088534Sjoerg    ", f=" INTPTR_FORMAT "",
18130300Sjoerg    p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f)
18230300Sjoerg  );
18330300Sjoerg}
1844910Swollman
18530300Sjoerg
18630300Sjoerginline void assert_different_registers(
18730300Sjoerg  AbstractRegister a,
18830300Sjoerg  AbstractRegister b,
18930300Sjoerg  AbstractRegister c,
19030300Sjoerg  AbstractRegister d,
19130300Sjoerg  AbstractRegister e,
19230300Sjoerg  AbstractRegister f,
19330300Sjoerg  AbstractRegister g
19430300Sjoerg) {
19530300Sjoerg  assert(
19630300Sjoerg    a != b && a != c && a != d && a != e && a != f && a != g
19730300Sjoerg           && b != c && b != d && b != e && b != f && b != g
19830300Sjoerg                     && c != d && c != e && c != f && c != g
19925944Sjoerg                               && d != e && d != f && d != g
20025944Sjoerg                                         && e != f && e != g
20125944Sjoerg                                                   && f != g,
20225944Sjoerg    "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
20325944Sjoerg    ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
20425944Sjoerg    ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT "",
20525944Sjoerg    p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g)
20625944Sjoerg  );
20725944Sjoerg}
20825944Sjoerg
20925944Sjoerg
21025944Sjoerginline void assert_different_registers(
2114910Swollman  AbstractRegister a,
21211189Sjkh  AbstractRegister b,
21311189Sjkh  AbstractRegister c,
21411189Sjkh  AbstractRegister d,
2154910Swollman  AbstractRegister e,
2164910Swollman  AbstractRegister f,
2174910Swollman  AbstractRegister g,
2184910Swollman  AbstractRegister h
21911189Sjkh) {
22011189Sjkh  assert(
22111189Sjkh    a != b && a != c && a != d && a != e && a != f && a != g && a != h
2224910Swollman           && b != c && b != d && b != e && b != f && b != g && b != h
2234910Swollman                     && c != d && c != e && c != f && c != g && c != h
2244910Swollman                               && d != e && d != f && d != g && d != h
2254910Swollman                                         && e != f && e != g && e != h
22611189Sjkh                                                   && f != g && f != h
22711189Sjkh                                                             && g != h,
22811189Sjkh    "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
22911189Sjkh    ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
23011189Sjkh    ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT "",
23111189Sjkh    p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h)
2324910Swollman  );
2334910Swollman}
2344910Swollman
23525944Sjoerg
23625944Sjoerginline void assert_different_registers(
23725944Sjoerg  AbstractRegister a,
23825944Sjoerg  AbstractRegister b,
23925944Sjoerg  AbstractRegister c,
24025944Sjoerg  AbstractRegister d,
24125944Sjoerg  AbstractRegister e,
24225944Sjoerg  AbstractRegister f,
24325944Sjoerg  AbstractRegister g,
24425944Sjoerg  AbstractRegister h,
24525944Sjoerg  AbstractRegister i
24625944Sjoerg) {
24725944Sjoerg  assert(
24825944Sjoerg    a != b && a != c && a != d && a != e && a != f && a != g && a != h && a != i
24925944Sjoerg           && b != c && b != d && b != e && b != f && b != g && b != h && b != i
25025944Sjoerg                     && c != d && c != e && c != f && c != g && c != h && c != i
25125944Sjoerg                               && d != e && d != f && d != g && d != h && d != i
25225944Sjoerg                                         && e != f && e != g && e != h && e != i
25325944Sjoerg                                                   && f != g && f != h && f != i
25425944Sjoerg                                                             && g != h && g != i
25525944Sjoerg                                                                       && h != i,
25625944Sjoerg    "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
25725944Sjoerg    ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
25825944Sjoerg    ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT
25925944Sjoerg    ", i=" INTPTR_FORMAT "",
26025944Sjoerg    p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i)
26125944Sjoerg  );
26225944Sjoerg}
26325944Sjoerg
26425944Sjoerginline void assert_different_registers(
26525944Sjoerg  AbstractRegister a,
26625944Sjoerg  AbstractRegister b,
26712820Sphk  AbstractRegister c,
26842065Sphk  AbstractRegister d,
26930300Sjoerg  AbstractRegister e,
27040008Sjoerg  AbstractRegister f,
2714910Swollman  AbstractRegister g,
27242065Sphk  AbstractRegister h,
27340008Sjoerg  AbstractRegister i,
27440008Sjoerg  AbstractRegister j
27540008Sjoerg) {
27640008Sjoerg  assert(
27740008Sjoerg    a != b && a != c && a != d && a != e && a != f && a != g && a != h && a != i && a != j
27840008Sjoerg           && b != c && b != d && b != e && b != f && b != g && b != h && b != i && b != j
27940008Sjoerg                     && c != d && c != e && c != f && c != g && c != h && c != i && c != j
2804910Swollman                               && d != e && d != f && d != g && d != h && d != i && d != j
2814910Swollman                                         && e != f && e != g && e != h && e != i && e != j
2824910Swollman                                                   && f != g && f != h && f != i && f != j
2834910Swollman                                                             && g != h && g != i && g != j
2844910Swollman                                                                       && h != i && h != j
28530300Sjoerg                                                                                 && i != j,
28630300Sjoerg    "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
2874910Swollman    ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
28811189Sjkh    ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT
2894910Swollman    ", i=" INTPTR_FORMAT ", j=" INTPTR_FORMAT "",
2904910Swollman    p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i), p2i(j)
2914910Swollman  );
2924910Swollman}
2934910Swollman
29425944Sjoerginline void assert_different_registers(
29525944Sjoerg  AbstractRegister a,
29625944Sjoerg  AbstractRegister b,
29725944Sjoerg  AbstractRegister c,
29811189Sjkh  AbstractRegister d,
29930300Sjoerg  AbstractRegister e,
30025944Sjoerg  AbstractRegister f,
3014910Swollman  AbstractRegister g,
30225944Sjoerg  AbstractRegister h,
30325944Sjoerg  AbstractRegister i,
30425944Sjoerg  AbstractRegister j,
30525944Sjoerg  AbstractRegister k
30625944Sjoerg) {
30725944Sjoerg  assert(
30825944Sjoerg    a != b && a != c && a != d && a != e && a != f && a != g && a != h && a != i && a != j && a !=k
30942104Sphk           && b != c && b != d && b != e && b != f && b != g && b != h && b != i && b != j && b !=k
31025944Sjoerg                     && c != d && c != e && c != f && c != g && c != h && c != i && c != j && c !=k
31125944Sjoerg                               && d != e && d != f && d != g && d != h && d != i && d != j && d !=k
31230300Sjoerg                                         && e != f && e != g && e != h && e != i && e != j && e !=k
31342104Sphk                                                   && f != g && f != h && f != i && f != j && f !=k
31430300Sjoerg                                                             && g != h && g != i && g != j && g !=k
31525944Sjoerg                                                                       && h != i && h != j && h !=k
31625944Sjoerg                                                                                 && i != j && i !=k
31725944Sjoerg                                                                                           && j !=k,
31825944Sjoerg    "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
31925944Sjoerg    ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
32025944Sjoerg    ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT
32125944Sjoerg    ", i=" INTPTR_FORMAT ", j=" INTPTR_FORMAT ", k=" INTPTR_FORMAT "",
32230300Sjoerg    p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i), p2i(j), p2i(k)
32330300Sjoerg  );
32425944Sjoerg}
32525944Sjoerg
32625944Sjoerginline void assert_different_registers(
32725944Sjoerg  AbstractRegister a,
32825944Sjoerg  AbstractRegister b,
32925944Sjoerg  AbstractRegister c,
33025944Sjoerg  AbstractRegister d,
33125944Sjoerg  AbstractRegister e,
33225944Sjoerg  AbstractRegister f,
33325944Sjoerg  AbstractRegister g,
33425944Sjoerg  AbstractRegister h,
33525944Sjoerg  AbstractRegister i,
33625944Sjoerg  AbstractRegister j,
33725944Sjoerg  AbstractRegister k,
33830300Sjoerg  AbstractRegister l
33930300Sjoerg) {
34025944Sjoerg  assert(
34125944Sjoerg    a != b && a != c && a != d && a != e && a != f && a != g && a != h && a != i && a != j && a !=k && a !=l
34225944Sjoerg           && b != c && b != d && b != e && b != f && b != g && b != h && b != i && b != j && b !=k && b !=l
34325944Sjoerg                     && c != d && c != e && c != f && c != g && c != h && c != i && c != j && c !=k && c !=l
34425944Sjoerg                               && d != e && d != f && d != g && d != h && d != i && d != j && d !=k && d !=l
34525944Sjoerg                                         && e != f && e != g && e != h && e != i && e != j && e !=k && e !=l
34625944Sjoerg                                                   && f != g && f != h && f != i && f != j && f !=k && f !=l
34725944Sjoerg                                                             && g != h && g != i && g != j && g !=k && g !=l
34825944Sjoerg                                                                       && h != i && h != j && h !=k && h !=l
34925944Sjoerg                                                                                 && i != j && i !=k && i !=l
35025944Sjoerg                                                                                           && j !=k && j !=l
35125944Sjoerg                                                                                                    && k !=l,
35225944Sjoerg    "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
35325944Sjoerg    ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
35425944Sjoerg    ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT
35525944Sjoerg    ", i=" INTPTR_FORMAT ", j=" INTPTR_FORMAT ", k=" INTPTR_FORMAT
35678064Sume    ", l=" INTPTR_FORMAT "",
35778064Sume    p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i), p2i(j), p2i(k), p2i(l)
35878064Sume  );
35978064Sume}
36078064Sume
36178064Sume#endif // SHARE_VM_ASM_REGISTER_HPP
36278064Sume