--- old/src/cpu/x86/vm/register_x86.hpp 2014-04-24 15:53:03.000000000 -1000 +++ new/src/cpu/x86/vm/register_x86.hpp 2014-04-24 15:53:03.000000000 -1000 @@ -31,17 +31,10 @@ class VMRegImpl; typedef VMRegImpl* VMReg; -// Use Register as shortcut -class RegisterImpl; -typedef RegisterImpl* Register; - - -// The implementation of integer registers for the ia32 architecture -inline Register as_Register(int encoding) { - return (Register)(intptr_t) encoding; -} - -class RegisterImpl: public AbstractRegisterImpl { +/** + * The implementation of integer registers for the IA32 architecture. + */ +class Register: public AbstractRegister { public: enum { #ifndef AMD64 @@ -53,93 +46,111 @@ #endif // AMD64 }; + /** + * Constructor to construct an invalid register. + */ + Register() : AbstractRegister(-1) {} + + Register(int encoding) : AbstractRegister(encoding) {} + // derived registers, offsets, and addresses - Register successor() const { return as_Register(encoding() + 1); } + Register successor() const { + return Register(encoding() + 1); + } // construction inline friend Register as_Register(int encoding); - VMReg as_VMReg(); + VMReg as_VMReg() const; + + bool is_valid() const { + return 0 <= encoding() && encoding() < number_of_registers; + } + + bool has_byte_register() const { + return 0 <= encoding() && encoding() < number_of_byte_registers; + } - // accessors - int encoding() const { assert(is_valid(), "invalid register"); return (intptr_t)this; } - bool is_valid() const { return 0 <= (intptr_t)this && (intptr_t)this < number_of_registers; } - bool has_byte_register() const { return 0 <= (intptr_t)this && (intptr_t)this < number_of_byte_registers; } const char* name() const; }; -// The integer registers of the ia32/amd64 architecture +inline Register as_Register(int encoding) { + return Register(encoding); +} -CONSTANT_REGISTER_DECLARATION(Register, noreg, (-1)); +/** + * The implementation of floating point registers for the IA32 architecture. + */ +class FloatRegister: public AbstractRegister { + public: + enum { + number_of_registers = 8 + }; + /** + * Constructor to construct an invalid register. + */ + FloatRegister() : AbstractRegister(-1) {} -CONSTANT_REGISTER_DECLARATION(Register, rax, (0)); -CONSTANT_REGISTER_DECLARATION(Register, rcx, (1)); -CONSTANT_REGISTER_DECLARATION(Register, rdx, (2)); -CONSTANT_REGISTER_DECLARATION(Register, rbx, (3)); -CONSTANT_REGISTER_DECLARATION(Register, rsp, (4)); -CONSTANT_REGISTER_DECLARATION(Register, rbp, (5)); -CONSTANT_REGISTER_DECLARATION(Register, rsi, (6)); -CONSTANT_REGISTER_DECLARATION(Register, rdi, (7)); -#ifdef AMD64 -CONSTANT_REGISTER_DECLARATION(Register, r8, (8)); -CONSTANT_REGISTER_DECLARATION(Register, r9, (9)); -CONSTANT_REGISTER_DECLARATION(Register, r10, (10)); -CONSTANT_REGISTER_DECLARATION(Register, r11, (11)); -CONSTANT_REGISTER_DECLARATION(Register, r12, (12)); -CONSTANT_REGISTER_DECLARATION(Register, r13, (13)); -CONSTANT_REGISTER_DECLARATION(Register, r14, (14)); -CONSTANT_REGISTER_DECLARATION(Register, r15, (15)); -#endif // AMD64 + FloatRegister(int encoding) : AbstractRegister(encoding) {} + + // construction + inline friend FloatRegister as_FloatRegister(int encoding); -// Use FloatRegister as shortcut -class FloatRegisterImpl; -typedef FloatRegisterImpl* FloatRegister; + VMReg as_VMReg() const; + + // derived registers, offsets, and addresses + FloatRegister successor() const { + return FloatRegister(encoding() + 1); + } + + bool is_valid() const { + return 0 <= encoding() && encoding() < number_of_registers; + } + + const char* name() const; +}; inline FloatRegister as_FloatRegister(int encoding) { - return (FloatRegister)(intptr_t) encoding; + return FloatRegister(encoding); } -// The implementation of floating point registers for the ia32 architecture -class FloatRegisterImpl: public AbstractRegisterImpl { +/** + * The implementation of MMX registers for the IA32 architecture. + */ +class MMXRegister: public AbstractRegister { public: enum { number_of_registers = 8 }; + MMXRegister(int encoding) : AbstractRegister(encoding) {} + // construction - inline friend FloatRegister as_FloatRegister(int encoding); + friend MMXRegister as_MMXRegister(int encoding); - VMReg as_VMReg(); + VMReg as_VMReg() const; // derived registers, offsets, and addresses - FloatRegister successor() const { return as_FloatRegister(encoding() + 1); } + MMXRegister successor() const { + return MMXRegister(encoding() + 1); + } + + bool is_valid() const { + return 0 <= encoding() && encoding() < number_of_registers; + } - // accessors - int encoding() const { assert(is_valid(), "invalid register"); return (intptr_t)this; } - bool is_valid() const { return 0 <= (intptr_t)this && (intptr_t)this < number_of_registers; } const char* name() const; - }; -// Use XMMRegister as shortcut -class XMMRegisterImpl; -typedef XMMRegisterImpl* XMMRegister; - -// Use MMXRegister as shortcut -class MMXRegisterImpl; -typedef MMXRegisterImpl* MMXRegister; - -inline XMMRegister as_XMMRegister(int encoding) { - return (XMMRegister)(intptr_t)encoding; -} - inline MMXRegister as_MMXRegister(int encoding) { - return (MMXRegister)(intptr_t)encoding; + return MMXRegister(encoding); } -// The implementation of XMM registers for the IA32 architecture -class XMMRegisterImpl: public AbstractRegisterImpl { +/** + * The implementation of XMM registers for the IA32 architecture. + */ +class XMMRegister: public AbstractRegister { public: enum { #ifndef AMD64 @@ -149,61 +160,38 @@ #endif // AMD64 }; + /** + * Constructor to construct an invalid register. + */ + XMMRegister() : AbstractRegister(-1) {} + + XMMRegister(int encoding) : AbstractRegister(encoding) {} + // construction friend XMMRegister as_XMMRegister(int encoding); - VMReg as_VMReg(); + VMReg as_VMReg() const; // derived registers, offsets, and addresses - XMMRegister successor() const { return as_XMMRegister(encoding() + 1); } + XMMRegister successor() const { + return XMMRegister(encoding() + 1); + } + + bool is_valid() const { + return 0 <= encoding() && encoding() < number_of_registers; + } - // accessors - int encoding() const { assert(is_valid(), err_msg("invalid register (%d)", (int)(intptr_t)this )); return (intptr_t)this; } - bool is_valid() const { return 0 <= (intptr_t)this && (intptr_t)this < number_of_registers; } const char* name() const; }; +inline XMMRegister as_XMMRegister(int encoding) { + return XMMRegister(encoding); +} -// The XMM registers, for P3 and up chips -CONSTANT_REGISTER_DECLARATION(XMMRegister, xnoreg , (-1)); -CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm0 , ( 0)); -CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm1 , ( 1)); -CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm2 , ( 2)); -CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm3 , ( 3)); -CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm4 , ( 4)); -CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm5 , ( 5)); -CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm6 , ( 6)); -CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm7 , ( 7)); -#ifdef AMD64 -CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm8, (8)); -CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm9, (9)); -CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm10, (10)); -CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm11, (11)); -CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm12, (12)); -CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm13, (13)); -CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm14, (14)); -CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm15, (15)); -#endif // AMD64 - -// Only used by the 32bit stubGenerator. These can't be described by vmreg and hence -// can't be described in oopMaps and therefore can't be used by the compilers (at least -// were deopt might wan't to see them). - -// The MMX registers, for P3 and up chips -CONSTANT_REGISTER_DECLARATION(MMXRegister, mnoreg , (-1)); -CONSTANT_REGISTER_DECLARATION(MMXRegister, mmx0 , ( 0)); -CONSTANT_REGISTER_DECLARATION(MMXRegister, mmx1 , ( 1)); -CONSTANT_REGISTER_DECLARATION(MMXRegister, mmx2 , ( 2)); -CONSTANT_REGISTER_DECLARATION(MMXRegister, mmx3 , ( 3)); -CONSTANT_REGISTER_DECLARATION(MMXRegister, mmx4 , ( 4)); -CONSTANT_REGISTER_DECLARATION(MMXRegister, mmx5 , ( 5)); -CONSTANT_REGISTER_DECLARATION(MMXRegister, mmx6 , ( 6)); -CONSTANT_REGISTER_DECLARATION(MMXRegister, mmx7 , ( 7)); - - -// Need to know the total number of registers of all sorts for SharedInfo. -// Define a class that exports it. -class ConcreteRegisterImpl : public AbstractRegisterImpl { +/** + * Need to know the total number of registers of all sorts for SharedInfo. Define a class that exports it. + */ +class ConcreteRegisterImpl : public AbstractRegister { public: enum { // A big enough number for C2: all the registers plus flags @@ -211,12 +199,12 @@ // There is no requirement that any ordering here matches any ordering c2 gives // it's optoregs. - number_of_registers = RegisterImpl::number_of_registers + + number_of_registers = Register::number_of_registers + #ifdef AMD64 - RegisterImpl::number_of_registers + // "H" half of a 64bit register + Register::number_of_registers + // "H" half of a 64bit register #endif // AMD64 - 2 * FloatRegisterImpl::number_of_registers + - 8 * XMMRegisterImpl::number_of_registers + + 2 * FloatRegister::number_of_registers + + 8 * XMMRegister::number_of_registers + 1 // eflags }; @@ -226,4 +214,180 @@ }; +// Calling convention +class Argument VALUE_OBJ_CLASS_SPEC { + public: + enum { +#ifdef _LP64 +#ifdef _WIN64 + n_int_register_parameters_c = 4, // rcx, rdx, r8, r9 (c_rarg0, c_rarg1, ...) + n_float_register_parameters_c = 4, // xmm0 - xmm3 (c_farg0, c_farg1, ... ) +#else + n_int_register_parameters_c = 6, // rdi, rsi, rdx, rcx, r8, r9 (c_rarg0, c_rarg1, ...) + n_float_register_parameters_c = 8, // xmm0 - xmm7 (c_farg0, c_farg1, ... ) +#endif // _WIN64 + n_int_register_parameters_j = 6, // j_rarg0, j_rarg1, ... + n_float_register_parameters_j = 8 // j_farg0, j_farg1, ... +#else + n_register_parameters = 0 // 0 registers used to pass arguments +#endif // _LP64 + }; +}; + +/* + * CPU registers. + */ +static const Register noreg(-1); + +static const Register rax(0); +static const Register rcx(1); +static const Register rdx(2); +static const Register rbx(3); +static const Register rsp(4); +static const Register rbp(5); +static const Register rsi(6); +static const Register rdi(7); + +#ifdef AMD64 +static const Register r8(8); +static const Register r9(9); +static const Register r10(10); +static const Register r11(11); +static const Register r12(12); +static const Register r13(13); +static const Register r14(14); +static const Register r15(15); +#endif + +/* + * XMM registers. + */ +static const XMMRegister xnoreg(-1); + +static const XMMRegister xmm0(0); +static const XMMRegister xmm1(1); +static const XMMRegister xmm2(2); +static const XMMRegister xmm3(3); +static const XMMRegister xmm4(4); +static const XMMRegister xmm5(5); +static const XMMRegister xmm6(6); +static const XMMRegister xmm7(7); + +#ifdef AMD64 +static const XMMRegister xmm8(8); +static const XMMRegister xmm9(9); +static const XMMRegister xmm10(10); +static const XMMRegister xmm11(11); +static const XMMRegister xmm12(12); +static const XMMRegister xmm13(13); +static const XMMRegister xmm14(14); +static const XMMRegister xmm15(15); +#endif + +/* + * MMX registers. + * + * Only used by the 32bit stubGenerator. These can't be described by vmreg and hence + * can't be described in oopMaps and therefore can't be used by the compilers (at least + * were deopt might wan't to see them). + */ +static const MMXRegister mnoreg(-1); + +static const MMXRegister mmx0(0); +static const MMXRegister mmx1(1); +static const MMXRegister mmx2(2); +static const MMXRegister mmx3(3); +static const MMXRegister mmx4(4); +static const MMXRegister mmx5(5); +static const MMXRegister mmx6(6); +static const MMXRegister mmx7(7); + +#ifdef _LP64 +// Symbolically name the register arguments used by the c calling convention. +// Windows is different from linux/solaris. So much for standards... + +#ifdef _WIN64 + +static const Register c_rarg0 = rcx; +static const Register c_rarg1 = rdx; +static const Register c_rarg2 = r8; +static const Register c_rarg3 = r9; + +static const XMMRegister c_farg0 = xmm0; +static const XMMRegister c_farg1 = xmm1; +static const XMMRegister c_farg2 = xmm2; +static const XMMRegister c_farg3 = xmm3; + +#else + +static const Register c_rarg0 = rdi; +static const Register c_rarg1 = rsi; +static const Register c_rarg2 = rdx; +static const Register c_rarg3 = rcx; +static const Register c_rarg4 = r8; +static const Register c_rarg5 = r9; + +static const XMMRegister c_farg0 = xmm0; +static const XMMRegister c_farg1 = xmm1; +static const XMMRegister c_farg2 = xmm2; +static const XMMRegister c_farg3 = xmm3; +static const XMMRegister c_farg4 = xmm4; +static const XMMRegister c_farg5 = xmm5; +static const XMMRegister c_farg6 = xmm6; +static const XMMRegister c_farg7 = xmm7; + +#endif // _WIN64 + +// Symbolically name the register arguments used by the Java calling convention. +// We have control over the convention for java so we can do what we please. +// What pleases us is to offset the java calling convention so that when +// we call a suitable jni method the arguments are lined up and we don't +// have to do little shuffling. A suitable jni method is non-static and a +// small number of arguments (two fewer args on windows) +// +// |-------------------------------------------------------| +// | c_rarg0 c_rarg1 c_rarg2 c_rarg3 c_rarg4 c_rarg5 | +// |-------------------------------------------------------| +// | rcx rdx r8 r9 rdi* rsi* | windows (* not a c_rarg) +// | rdi rsi rdx rcx r8 r9 | solaris/linux +// |-------------------------------------------------------| +// | j_rarg5 j_rarg0 j_rarg1 j_rarg2 j_rarg3 j_rarg4 | +// |-------------------------------------------------------| + +static const Register j_rarg0 = c_rarg1; +static const Register j_rarg1 = c_rarg2; +static const Register j_rarg2 = c_rarg3; +// Windows runs out of register args here +static const Register j_rarg3 = NOT_WIN64(c_rarg4) WIN64_ONLY(rdi); +static const Register j_rarg4 = NOT_WIN64(c_rarg5) WIN64_ONLY(rsi); +static const Register j_rarg5 = c_rarg0; + +static const XMMRegister j_farg0 = xmm0; +static const XMMRegister j_farg1 = xmm1; +static const XMMRegister j_farg2 = xmm2; +static const XMMRegister j_farg3 = xmm3; +static const XMMRegister j_farg4 = xmm4; +static const XMMRegister j_farg5 = xmm5; +static const XMMRegister j_farg6 = xmm6; +static const XMMRegister j_farg7 = xmm7; + +static const Register rscratch1 = r10; // volatile +static const Register rscratch2 = r11; // volatile + +static const Register r12_heapbase = r12; // callee-saved +static const Register r15_thread = r15; // callee-saved + +#else +// rscratch1 will appear in 32bit code that is dead but of course must compile. +// Using noreg ensures if the dead code is incorrectly live and executed it +// will cause an assertion failure. + +static const Register rscratch1 = noreg; +static const Register rscratch2 = noreg; + +#endif // _LP64 + +// JSR 292 fixed register usages: +static const Register rbp_mh_SP_save = rbp; + #endif // CPU_X86_VM_REGISTER_X86_HPP