src/cpu/x86/vm/register_x86.hpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File
*** old/src/cpu/x86/vm/register_x86.hpp	Thu Apr 24 15:53:03 2014
--- new/src/cpu/x86/vm/register_x86.hpp	Thu Apr 24 15:53:03 2014

*** 29,49 **** --- 29,42 ---- #include "vm_version_x86.hpp" 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 number_of_registers = 8, number_of_byte_registers = 4
*** 51,229 **** --- 44,393 ---- number_of_registers = 16, number_of_byte_registers = 16 #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); } + return Register(encoding() + 1); + } // construction inline friend Register as_Register(int encoding); ! 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() 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 number_of_registers = 8 #else number_of_registers = 16 #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() const; // derived registers, offsets, and addresses ! XMMRegister successor() const { return as_XMMRegister(encoding() + 1); } + 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 // This number must be large enough to cover REG_COUNT (defined by c2) registers. // There is no requirement that any ordering here matches any ordering c2 gives // it's optoregs. - number_of_registers = RegisterImpl::number_of_registers + #ifdef AMD64 - RegisterImpl::number_of_registers + // "H" half of a 64bit register #endif // AMD64 - 2 * FloatRegisterImpl::number_of_registers + - 8 * XMMRegisterImpl::number_of_registers + 1 // eflags }; static const int max_gpr; static const int max_fpr; static const int max_xmm; }; + // 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

src/cpu/x86/vm/register_x86.hpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File