mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-11 14:11:36 +00:00
8292203: AArch64: Represent Registers as values
Reviewed-by: kvn, aph
This commit is contained in:
parent
251bff6bee
commit
2fe0ce0148
@ -1909,19 +1909,19 @@ static enum RC rc_class(OptoReg::Name reg) {
|
||||
}
|
||||
|
||||
// we have 32 int registers * 2 halves
|
||||
int slots_of_int_registers = RegisterImpl::max_slots_per_register * RegisterImpl::number_of_registers;
|
||||
int slots_of_int_registers = Register::number_of_registers * Register::max_slots_per_register;
|
||||
|
||||
if (reg < slots_of_int_registers) {
|
||||
return rc_int;
|
||||
}
|
||||
|
||||
// we have 32 float register * 8 halves
|
||||
int slots_of_float_registers = FloatRegisterImpl::max_slots_per_register * FloatRegisterImpl::number_of_registers;
|
||||
int slots_of_float_registers = FloatRegister::number_of_registers * FloatRegister::max_slots_per_register;
|
||||
if (reg < slots_of_int_registers + slots_of_float_registers) {
|
||||
return rc_float;
|
||||
}
|
||||
|
||||
int slots_of_predicate_registers = PRegisterImpl::max_slots_per_register * PRegisterImpl::number_of_registers;
|
||||
int slots_of_predicate_registers = PRegister::number_of_registers * PRegister::max_slots_per_register;
|
||||
if (reg < slots_of_int_registers + slots_of_float_registers + slots_of_predicate_registers) {
|
||||
return rc_predicate;
|
||||
}
|
||||
|
||||
@ -62,23 +62,23 @@ class Argument {
|
||||
};
|
||||
};
|
||||
|
||||
REGISTER_DECLARATION(Register, c_rarg0, r0);
|
||||
REGISTER_DECLARATION(Register, c_rarg1, r1);
|
||||
REGISTER_DECLARATION(Register, c_rarg2, r2);
|
||||
REGISTER_DECLARATION(Register, c_rarg3, r3);
|
||||
REGISTER_DECLARATION(Register, c_rarg4, r4);
|
||||
REGISTER_DECLARATION(Register, c_rarg5, r5);
|
||||
REGISTER_DECLARATION(Register, c_rarg6, r6);
|
||||
REGISTER_DECLARATION(Register, c_rarg7, r7);
|
||||
constexpr Register c_rarg0 = r0;
|
||||
constexpr Register c_rarg1 = r1;
|
||||
constexpr Register c_rarg2 = r2;
|
||||
constexpr Register c_rarg3 = r3;
|
||||
constexpr Register c_rarg4 = r4;
|
||||
constexpr Register c_rarg5 = r5;
|
||||
constexpr Register c_rarg6 = r6;
|
||||
constexpr Register c_rarg7 = r7;
|
||||
|
||||
REGISTER_DECLARATION(FloatRegister, c_farg0, v0);
|
||||
REGISTER_DECLARATION(FloatRegister, c_farg1, v1);
|
||||
REGISTER_DECLARATION(FloatRegister, c_farg2, v2);
|
||||
REGISTER_DECLARATION(FloatRegister, c_farg3, v3);
|
||||
REGISTER_DECLARATION(FloatRegister, c_farg4, v4);
|
||||
REGISTER_DECLARATION(FloatRegister, c_farg5, v5);
|
||||
REGISTER_DECLARATION(FloatRegister, c_farg6, v6);
|
||||
REGISTER_DECLARATION(FloatRegister, c_farg7, v7);
|
||||
constexpr FloatRegister c_farg0 = v0;
|
||||
constexpr FloatRegister c_farg1 = v1;
|
||||
constexpr FloatRegister c_farg2 = v2;
|
||||
constexpr FloatRegister c_farg3 = v3;
|
||||
constexpr FloatRegister c_farg4 = v4;
|
||||
constexpr FloatRegister c_farg5 = v5;
|
||||
constexpr FloatRegister c_farg6 = v6;
|
||||
constexpr FloatRegister c_farg7 = v7;
|
||||
|
||||
// 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.
|
||||
@ -96,25 +96,25 @@ REGISTER_DECLARATION(FloatRegister, c_farg7, v7);
|
||||
// |--------------------------------------------------------------------|
|
||||
|
||||
|
||||
REGISTER_DECLARATION(Register, j_rarg0, c_rarg1);
|
||||
REGISTER_DECLARATION(Register, j_rarg1, c_rarg2);
|
||||
REGISTER_DECLARATION(Register, j_rarg2, c_rarg3);
|
||||
REGISTER_DECLARATION(Register, j_rarg3, c_rarg4);
|
||||
REGISTER_DECLARATION(Register, j_rarg4, c_rarg5);
|
||||
REGISTER_DECLARATION(Register, j_rarg5, c_rarg6);
|
||||
REGISTER_DECLARATION(Register, j_rarg6, c_rarg7);
|
||||
REGISTER_DECLARATION(Register, j_rarg7, c_rarg0);
|
||||
constexpr Register j_rarg0 = c_rarg1;
|
||||
constexpr Register j_rarg1 = c_rarg2;
|
||||
constexpr Register j_rarg2 = c_rarg3;
|
||||
constexpr Register j_rarg3 = c_rarg4;
|
||||
constexpr Register j_rarg4 = c_rarg5;
|
||||
constexpr Register j_rarg5 = c_rarg6;
|
||||
constexpr Register j_rarg6 = c_rarg7;
|
||||
constexpr Register j_rarg7 = c_rarg0;
|
||||
|
||||
// Java floating args are passed as per C
|
||||
|
||||
REGISTER_DECLARATION(FloatRegister, j_farg0, v0);
|
||||
REGISTER_DECLARATION(FloatRegister, j_farg1, v1);
|
||||
REGISTER_DECLARATION(FloatRegister, j_farg2, v2);
|
||||
REGISTER_DECLARATION(FloatRegister, j_farg3, v3);
|
||||
REGISTER_DECLARATION(FloatRegister, j_farg4, v4);
|
||||
REGISTER_DECLARATION(FloatRegister, j_farg5, v5);
|
||||
REGISTER_DECLARATION(FloatRegister, j_farg6, v6);
|
||||
REGISTER_DECLARATION(FloatRegister, j_farg7, v7);
|
||||
constexpr FloatRegister j_farg0 = v0;
|
||||
constexpr FloatRegister j_farg1 = v1;
|
||||
constexpr FloatRegister j_farg2 = v2;
|
||||
constexpr FloatRegister j_farg3 = v3;
|
||||
constexpr FloatRegister j_farg4 = v4;
|
||||
constexpr FloatRegister j_farg5 = v5;
|
||||
constexpr FloatRegister j_farg6 = v6;
|
||||
constexpr FloatRegister j_farg7 = v7;
|
||||
|
||||
// registers used to hold VM data either temporarily within a method
|
||||
// or across method calls
|
||||
@ -123,40 +123,28 @@ REGISTER_DECLARATION(FloatRegister, j_farg7, v7);
|
||||
|
||||
// r8 is used for indirect result location return
|
||||
// we use it and r9 as scratch registers
|
||||
REGISTER_DECLARATION(Register, rscratch1, r8);
|
||||
REGISTER_DECLARATION(Register, rscratch2, r9);
|
||||
constexpr Register rscratch1 = r8;
|
||||
constexpr Register rscratch2 = r9;
|
||||
|
||||
// current method -- must be in a call-clobbered register
|
||||
REGISTER_DECLARATION(Register, rmethod, r12);
|
||||
constexpr Register rmethod = r12;
|
||||
|
||||
// non-volatile (callee-save) registers are r16-29
|
||||
// of which the following are dedicated global state
|
||||
|
||||
// link register
|
||||
REGISTER_DECLARATION(Register, lr, r30);
|
||||
// frame pointer
|
||||
REGISTER_DECLARATION(Register, rfp, r29);
|
||||
// current thread
|
||||
REGISTER_DECLARATION(Register, rthread, r28);
|
||||
// base of heap
|
||||
REGISTER_DECLARATION(Register, rheapbase, r27);
|
||||
// constant pool cache
|
||||
REGISTER_DECLARATION(Register, rcpool, r26);
|
||||
// r25 is a callee-saved temp
|
||||
// REGISTER_DECLARATION(Register, unused, r25);
|
||||
// locals on stack
|
||||
REGISTER_DECLARATION(Register, rlocals, r24);
|
||||
// bytecode pointer
|
||||
REGISTER_DECLARATION(Register, rbcp, r22);
|
||||
// Dispatch table base
|
||||
REGISTER_DECLARATION(Register, rdispatch, r21);
|
||||
// Java expression stack pointer
|
||||
REGISTER_DECLARATION(Register, esp, r20);
|
||||
// Sender's SP while in interpreter
|
||||
REGISTER_DECLARATION(Register, r19_sender_sp, r19);
|
||||
constexpr Register lr = r30; // link register
|
||||
constexpr Register rfp = r29; // frame pointer
|
||||
constexpr Register rthread = r28; // current thread
|
||||
constexpr Register rheapbase = r27; // base of heap
|
||||
constexpr Register rcpool = r26; // constant pool cache
|
||||
constexpr Register rlocals = r24; // locals on stack
|
||||
constexpr Register rbcp = r22; // bytecode pointer
|
||||
constexpr Register rdispatch = r21; // dispatch table base
|
||||
constexpr Register esp = r20; // Java expression stack pointer
|
||||
constexpr Register r19_sender_sp = r19; // sender's SP while in interpreter
|
||||
|
||||
// Preserved predicate register with all elements set TRUE.
|
||||
REGISTER_DECLARATION(PRegister, ptrue, p7);
|
||||
constexpr PRegister ptrue = p7;
|
||||
|
||||
#define assert_cond(ARG1) assert(ARG1, #ARG1)
|
||||
|
||||
@ -277,29 +265,29 @@ public:
|
||||
}
|
||||
|
||||
void rf(Register r, int lsb) {
|
||||
f(r->encoding_nocheck(), lsb + 4, lsb);
|
||||
f(r->raw_encoding(), lsb + 4, lsb);
|
||||
}
|
||||
|
||||
// reg|ZR
|
||||
void zrf(Register r, int lsb) {
|
||||
f(r->encoding_nocheck() - (r == zr), lsb + 4, lsb);
|
||||
f(r->raw_encoding() - (r == zr), lsb + 4, lsb);
|
||||
}
|
||||
|
||||
// reg|SP
|
||||
void srf(Register r, int lsb) {
|
||||
f(r == sp ? 31 : r->encoding_nocheck(), lsb + 4, lsb);
|
||||
f(r == sp ? 31 : r->raw_encoding(), lsb + 4, lsb);
|
||||
}
|
||||
|
||||
void rf(FloatRegister r, int lsb) {
|
||||
f(r->encoding_nocheck(), lsb + 4, lsb);
|
||||
f(r->raw_encoding(), lsb + 4, lsb);
|
||||
}
|
||||
|
||||
void prf(PRegister r, int lsb) {
|
||||
f(r->encoding_nocheck(), lsb + 3, lsb);
|
||||
f(r->raw_encoding(), lsb + 3, lsb);
|
||||
}
|
||||
|
||||
void pgrf(PRegister r, int lsb) {
|
||||
f(r->encoding_nocheck(), lsb + 2, lsb);
|
||||
f(r->raw_encoding(), lsb + 2, lsb);
|
||||
}
|
||||
|
||||
unsigned get(int msb = 31, int lsb = 0) {
|
||||
@ -329,7 +317,7 @@ class Post : public PrePost {
|
||||
Register _idx;
|
||||
bool _is_postreg;
|
||||
public:
|
||||
Post(Register reg, int o) : PrePost(reg, o) { _idx = NULL; _is_postreg = false; }
|
||||
Post(Register reg, int o) : PrePost(reg, o) { _idx = noreg; _is_postreg = false; }
|
||||
Post(Register reg, Register idx) : PrePost(reg, 0) { _idx = idx; _is_postreg = true; }
|
||||
Register idx_reg() { return _idx; }
|
||||
bool is_postreg() {return _is_postreg; }
|
||||
@ -627,8 +615,7 @@ class InternalAddress: public Address {
|
||||
InternalAddress(address target) : Address(target, relocInfo::internal_word_type) {}
|
||||
};
|
||||
|
||||
const int FPUStateSizeInWords = FloatRegisterImpl::number_of_registers *
|
||||
FloatRegisterImpl::save_slots_per_register;
|
||||
const int FPUStateSizeInWords = FloatRegister::number_of_registers * FloatRegister::save_slots_per_register;
|
||||
|
||||
typedef enum {
|
||||
PLDL1KEEP = 0b00000, PLDL1STRM, PLDL2KEEP, PLDL2STRM, PLDL3KEEP, PLDL3STRM,
|
||||
|
||||
@ -41,8 +41,8 @@ enum {
|
||||
|
||||
// registers
|
||||
enum {
|
||||
pd_nof_cpu_regs_frame_map = RegisterImpl::number_of_registers, // number of registers used during code emission
|
||||
pd_nof_fpu_regs_frame_map = FloatRegisterImpl::number_of_registers, // number of registers used during code emission
|
||||
pd_nof_cpu_regs_frame_map = Register::number_of_registers, // number of GP registers used during code emission
|
||||
pd_nof_fpu_regs_frame_map = FloatRegister::number_of_registers, // number of FP registers used during code emission
|
||||
|
||||
pd_nof_caller_save_cpu_regs_frame_map = 19 - 2 /* rscratch1 and rscratch2 */ R18_RESERVED_ONLY(- 1), // number of registers killed by calls
|
||||
pd_nof_caller_save_fpu_regs_frame_map = 32, // number of registers killed by calls
|
||||
|
||||
@ -175,11 +175,11 @@ void CodeInstaller::pd_relocate_poll(address pc, jint mark, JVMCI_TRAPS) {
|
||||
|
||||
// convert JVMCI register indices (as used in oop maps) to HotSpot registers
|
||||
VMReg CodeInstaller::get_hotspot_reg(jint jvmci_reg, JVMCI_TRAPS) {
|
||||
if (jvmci_reg < RegisterImpl::number_of_registers) {
|
||||
if (jvmci_reg < Register::number_of_registers) {
|
||||
return as_Register(jvmci_reg)->as_VMReg();
|
||||
} else {
|
||||
jint floatRegisterNumber = jvmci_reg - RegisterImpl::number_of_declared_registers;
|
||||
if (floatRegisterNumber >= 0 && floatRegisterNumber < FloatRegisterImpl::number_of_registers) {
|
||||
jint floatRegisterNumber = jvmci_reg - Register::number_of_declared_registers;
|
||||
if (floatRegisterNumber >= 0 && floatRegisterNumber < FloatRegister::number_of_registers) {
|
||||
return as_FloatRegister(floatRegisterNumber)->as_VMReg();
|
||||
}
|
||||
JVMCI_ERROR_NULL("invalid register number: %d", jvmci_reg);
|
||||
|
||||
@ -2198,7 +2198,7 @@ int MacroAssembler::push(unsigned int bitset, Register stack) {
|
||||
regs[count++] = reg;
|
||||
bitset >>= 1;
|
||||
}
|
||||
regs[count++] = zr->encoding_nocheck();
|
||||
regs[count++] = zr->raw_encoding();
|
||||
count &= ~1; // Only push an even number of regs
|
||||
|
||||
if (count) {
|
||||
@ -2228,7 +2228,7 @@ int MacroAssembler::pop(unsigned int bitset, Register stack) {
|
||||
regs[count++] = reg;
|
||||
bitset >>= 1;
|
||||
}
|
||||
regs[count++] = zr->encoding_nocheck();
|
||||
regs[count++] = zr->raw_encoding();
|
||||
count &= ~1;
|
||||
|
||||
for (int i = 2; i < count; i += 2) {
|
||||
@ -2383,9 +2383,9 @@ int MacroAssembler::push_p(unsigned int bitset, Register stack) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned char regs[PRegisterImpl::number_of_saved_registers];
|
||||
unsigned char regs[PRegister::number_of_saved_registers];
|
||||
int count = 0;
|
||||
for (int reg = 0; reg < PRegisterImpl::number_of_saved_registers; reg++) {
|
||||
for (int reg = 0; reg < PRegister::number_of_saved_registers; reg++) {
|
||||
if (1 & bitset)
|
||||
regs[count++] = reg;
|
||||
bitset >>= 1;
|
||||
@ -2420,9 +2420,9 @@ int MacroAssembler::pop_p(unsigned int bitset, Register stack) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned char regs[PRegisterImpl::number_of_saved_registers];
|
||||
unsigned char regs[PRegister::number_of_saved_registers];
|
||||
int count = 0;
|
||||
for (int reg = 0; reg < PRegisterImpl::number_of_saved_registers; reg++) {
|
||||
for (int reg = 0; reg < PRegister::number_of_saved_registers; reg++) {
|
||||
if (1 & bitset)
|
||||
regs[count++] = reg;
|
||||
bitset >>= 1;
|
||||
@ -2910,8 +2910,8 @@ void MacroAssembler::push_CPU_state(bool save_vectors, bool use_sve,
|
||||
int sve_vector_size_in_bytes, int total_predicate_in_bytes) {
|
||||
push(RegSet::range(r0, r29), sp); // integer registers except lr & sp
|
||||
if (save_vectors && use_sve && sve_vector_size_in_bytes > 16) {
|
||||
sub(sp, sp, sve_vector_size_in_bytes * FloatRegisterImpl::number_of_registers);
|
||||
for (int i = 0; i < FloatRegisterImpl::number_of_registers; i++) {
|
||||
sub(sp, sp, sve_vector_size_in_bytes * FloatRegister::number_of_registers);
|
||||
for (int i = 0; i < FloatRegister::number_of_registers; i++) {
|
||||
sve_str(as_FloatRegister(i), Address(sp, i));
|
||||
}
|
||||
} else {
|
||||
@ -2926,7 +2926,7 @@ void MacroAssembler::push_CPU_state(bool save_vectors, bool use_sve,
|
||||
}
|
||||
if (save_vectors && use_sve && total_predicate_in_bytes > 0) {
|
||||
sub(sp, sp, total_predicate_in_bytes);
|
||||
for (int i = 0; i < PRegisterImpl::number_of_saved_registers; i++) {
|
||||
for (int i = 0; i < PRegister::number_of_saved_registers; i++) {
|
||||
sve_str(as_PRegister(i), Address(sp, i));
|
||||
}
|
||||
}
|
||||
@ -2935,16 +2935,16 @@ void MacroAssembler::push_CPU_state(bool save_vectors, bool use_sve,
|
||||
void MacroAssembler::pop_CPU_state(bool restore_vectors, bool use_sve,
|
||||
int sve_vector_size_in_bytes, int total_predicate_in_bytes) {
|
||||
if (restore_vectors && use_sve && total_predicate_in_bytes > 0) {
|
||||
for (int i = PRegisterImpl::number_of_saved_registers - 1; i >= 0; i--) {
|
||||
for (int i = PRegister::number_of_saved_registers - 1; i >= 0; i--) {
|
||||
sve_ldr(as_PRegister(i), Address(sp, i));
|
||||
}
|
||||
add(sp, sp, total_predicate_in_bytes);
|
||||
}
|
||||
if (restore_vectors && use_sve && sve_vector_size_in_bytes > 16) {
|
||||
for (int i = FloatRegisterImpl::number_of_registers - 1; i >= 0; i--) {
|
||||
for (int i = FloatRegister::number_of_registers - 1; i >= 0; i--) {
|
||||
sve_ldr(as_FloatRegister(i), Address(sp, i));
|
||||
}
|
||||
add(sp, sp, sve_vector_size_in_bytes * FloatRegisterImpl::number_of_registers);
|
||||
add(sp, sp, sve_vector_size_in_bytes * FloatRegister::number_of_registers);
|
||||
} else {
|
||||
int step = (restore_vectors ? 8 : 4) * wordSize;
|
||||
for (int i = 0; i <= 28; i += 4)
|
||||
|
||||
@ -231,27 +231,27 @@ public:
|
||||
br(Assembler::EQ, _rounds_52);
|
||||
}
|
||||
break;
|
||||
case 2: aes_round(_data, _subkeys + 0); break;
|
||||
case 3: aes_round(_data, _subkeys + 1); break;
|
||||
case 2: aes_round(_data, as_FloatRegister(_subkeys->encoding() + 0)); break;
|
||||
case 3: aes_round(_data, as_FloatRegister(_subkeys->encoding() + 1)); break;
|
||||
case 4:
|
||||
if (_once) bind(_rounds_52);
|
||||
break;
|
||||
case 5: aes_round(_data, _subkeys + 2); break;
|
||||
case 6: aes_round(_data, _subkeys + 3); break;
|
||||
case 5: aes_round(_data, as_FloatRegister(_subkeys->encoding() + 2)); break;
|
||||
case 6: aes_round(_data, as_FloatRegister(_subkeys->encoding() + 3)); break;
|
||||
case 7:
|
||||
if (_once) bind(_rounds_44);
|
||||
break;
|
||||
case 8: aes_round(_data, _subkeys + 4); break;
|
||||
case 9: aes_round(_data, _subkeys + 5); break;
|
||||
case 10: aes_round(_data, _subkeys + 6); break;
|
||||
case 11: aes_round(_data, _subkeys + 7); break;
|
||||
case 12: aes_round(_data, _subkeys + 8); break;
|
||||
case 13: aes_round(_data, _subkeys + 9); break;
|
||||
case 14: aes_round(_data, _subkeys + 10); break;
|
||||
case 15: aes_round(_data, _subkeys + 11); break;
|
||||
case 16: aes_round(_data, _subkeys + 12); break;
|
||||
case 17: aese(_data, _subkeys + 13); break;
|
||||
case 18: eor(_data, T16B, _data, _subkeys + 14); break;
|
||||
case 8: aes_round(_data, as_FloatRegister(_subkeys->encoding() + 4)); break;
|
||||
case 9: aes_round(_data, as_FloatRegister(_subkeys->encoding() + 5)); break;
|
||||
case 10: aes_round(_data, as_FloatRegister(_subkeys->encoding() + 6)); break;
|
||||
case 11: aes_round(_data, as_FloatRegister(_subkeys->encoding() + 7)); break;
|
||||
case 12: aes_round(_data, as_FloatRegister(_subkeys->encoding() + 8)); break;
|
||||
case 13: aes_round(_data, as_FloatRegister(_subkeys->encoding() + 9)); break;
|
||||
case 14: aes_round(_data, as_FloatRegister(_subkeys->encoding() + 10)); break;
|
||||
case 15: aes_round(_data, as_FloatRegister(_subkeys->encoding() + 11)); break;
|
||||
case 16: aes_round(_data, as_FloatRegister(_subkeys->encoding() + 12)); break;
|
||||
case 17: aese(_data, as_FloatRegister(_subkeys->encoding() + 13)); break;
|
||||
case 18: eor(_data, T16B, _data, as_FloatRegister(_subkeys->encoding() + 14)); break;
|
||||
case 19:
|
||||
if (_to != noreg) {
|
||||
st1(_data, T16B, _to);
|
||||
@ -264,7 +264,7 @@ public:
|
||||
virtual KernelGenerator *next() {
|
||||
return new AESKernelGenerator(this, _unrolls,
|
||||
_from, _to, _keylen,
|
||||
_data + 1, _subkeys, /*once*/false);
|
||||
_data->successor(), _subkeys, /*once*/false);
|
||||
}
|
||||
|
||||
virtual int length() { return 20; }
|
||||
@ -409,14 +409,14 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual KernelGenerator *next() {
|
||||
GHASHMultiplyGenerator *result = new GHASHMultiplyGenerator(*this);
|
||||
result->_result_lo += register_stride;
|
||||
result->_result_hi += register_stride;
|
||||
result->_b += register_stride;
|
||||
result->_tmp1 += register_stride;
|
||||
result->_tmp2 += register_stride;
|
||||
result->_tmp3 += register_stride;
|
||||
virtual KernelGenerator* next() {
|
||||
GHASHMultiplyGenerator* result = new GHASHMultiplyGenerator(*this);
|
||||
result->_result_lo = as_FloatRegister(result->_result_lo->encoding() + register_stride);
|
||||
result->_result_hi = as_FloatRegister(result->_result_hi->encoding() + register_stride);
|
||||
result->_b = as_FloatRegister(result->_b ->encoding() + register_stride);
|
||||
result->_tmp1 = as_FloatRegister(result->_tmp1 ->encoding() + register_stride);
|
||||
result->_tmp2 = as_FloatRegister(result->_tmp2 ->encoding() + register_stride);
|
||||
result->_tmp3 = as_FloatRegister(result->_tmp3 ->encoding() + register_stride);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -477,17 +477,17 @@ public:
|
||||
if (_data->is_valid() && _once) {
|
||||
assert(length() >= unrolls(), "not enough room for inteleaved loads");
|
||||
if (index < unrolls()) {
|
||||
ld1((_data + index*register_stride), T16B, post(r2, 0x10));
|
||||
ld1(as_FloatRegister(_data->encoding() + index*register_stride), T16B, post(r2, 0x10));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual KernelGenerator *next() {
|
||||
GHASHReduceGenerator *result = new GHASHReduceGenerator(*this);
|
||||
result->_result += register_stride;
|
||||
result->_hi += register_stride;
|
||||
result->_lo += register_stride;
|
||||
result->_t1 += register_stride;
|
||||
result->_result = as_FloatRegister(result->_result->encoding() + register_stride);
|
||||
result->_hi = as_FloatRegister(result->_hi ->encoding() + register_stride);
|
||||
result->_lo = as_FloatRegister(result->_lo ->encoding() + register_stride);
|
||||
result->_t1 = as_FloatRegister(result->_t1 ->encoding() + register_stride);
|
||||
result->_once = false;
|
||||
return result;
|
||||
}
|
||||
@ -582,7 +582,8 @@ void MacroAssembler::ghash_processBlocks_wide(address field_polynomial, Register
|
||||
// v0 contains the initial state. Clear the others.
|
||||
for (int i = 1; i < unrolls; i++) {
|
||||
int ofs = register_stride * i;
|
||||
eor(ofs+v0, T16B, ofs+v0, ofs+v0); // zero each state register
|
||||
FloatRegister v0_ofs = as_FloatRegister(v0->encoding() + ofs);
|
||||
eor(v0_ofs, T16B, v0_ofs, v0_ofs); // zero each state register
|
||||
}
|
||||
|
||||
ext(a1_xor_a0, T16B, Hprime, Hprime, 0x08); // long-swap subkeyH into a1_xor_a0
|
||||
@ -590,7 +591,8 @@ void MacroAssembler::ghash_processBlocks_wide(address field_polynomial, Register
|
||||
|
||||
// Load #unrolls blocks of data
|
||||
for (int ofs = 0; ofs < unrolls * register_stride; ofs += register_stride) {
|
||||
ld1(v2+ofs, T16B, post(data, 0x10));
|
||||
FloatRegister v2_ofs = as_FloatRegister(v2->encoding() + ofs);
|
||||
ld1(v2_ofs, T16B, post(data, 0x10));
|
||||
}
|
||||
|
||||
// Register assignments, replicated across 4 clones, v0 ... v23
|
||||
@ -623,8 +625,10 @@ void MacroAssembler::ghash_processBlocks_wide(address field_polynomial, Register
|
||||
|
||||
// Xor data into current state
|
||||
for (int ofs = 0; ofs < unrolls * register_stride; ofs += register_stride) {
|
||||
rbit((v2+ofs), T16B, (v2+ofs));
|
||||
eor((v2+ofs), T16B, v0+ofs, (v2+ofs)); // bit-swapped data ^ bit-swapped state
|
||||
FloatRegister v0_ofs = as_FloatRegister(v0->encoding() + ofs);
|
||||
FloatRegister v2_ofs = as_FloatRegister(v2->encoding() + ofs);
|
||||
rbit(v2_ofs, T16B, v2_ofs);
|
||||
eor(v2_ofs, T16B, v0_ofs, v2_ofs); // bit-swapped data ^ bit-swapped state
|
||||
}
|
||||
|
||||
// Generate fully-unrolled multiply-reduce in two stages.
|
||||
@ -651,24 +655,31 @@ void MacroAssembler::ghash_processBlocks_wide(address field_polynomial, Register
|
||||
// First, we multiply/reduce each clone by the appropriate power of H.
|
||||
for (int i = 0; i < unrolls; i++) {
|
||||
int ofs = register_stride * i;
|
||||
FloatRegister v0_ofs = as_FloatRegister(v0->encoding() + ofs);
|
||||
FloatRegister v1_ofs = as_FloatRegister(v1->encoding() + ofs);
|
||||
FloatRegister v2_ofs = as_FloatRegister(v2->encoding() + ofs);
|
||||
FloatRegister v3_ofs = as_FloatRegister(v3->encoding() + ofs);
|
||||
FloatRegister v4_ofs = as_FloatRegister(v4->encoding() + ofs);
|
||||
FloatRegister v5_ofs = as_FloatRegister(v5->encoding() + ofs);
|
||||
|
||||
ldrq(Hprime, Address(subkeyH, 16 * (unrolls - i - 1)));
|
||||
|
||||
rbit(v2+ofs, T16B, v2+ofs);
|
||||
eor(v2+ofs, T16B, ofs+v0, v2+ofs); // bit-swapped data ^ bit-swapped state
|
||||
rbit(v2_ofs, T16B, v2_ofs);
|
||||
eor(v2_ofs, T16B, v0_ofs, v2_ofs); // bit-swapped data ^ bit-swapped state
|
||||
|
||||
rev64(Hprime, T16B, Hprime);
|
||||
rbit(Hprime, T16B, Hprime);
|
||||
ext(a1_xor_a0, T16B, Hprime, Hprime, 0x08); // long-swap subkeyH into a1_xor_a0
|
||||
eor(a1_xor_a0, T16B, a1_xor_a0, Hprime); // xor subkeyH into subkeyL (Karatsuba: (A1+A0))
|
||||
ghash_modmul(/*result*/v0+ofs, /*result_lo*/v5+ofs, /*result_hi*/v4+ofs, /*b*/v2+ofs,
|
||||
ghash_modmul(/*result*/v0_ofs, /*result_lo*/v5_ofs, /*result_hi*/v4_ofs, /*b*/v2_ofs,
|
||||
Hprime, vzr, a1_xor_a0, p,
|
||||
/*temps*/v1+ofs, v3+ofs, /* reuse b*/v2+ofs);
|
||||
/*temps*/v1_ofs, v3_ofs, /* reuse b*/v2_ofs);
|
||||
}
|
||||
|
||||
// Then we sum the results.
|
||||
for (int i = 0; i < unrolls - 1; i++) {
|
||||
int ofs = register_stride * i;
|
||||
eor(v0, T16B, v0, v0 + register_stride + ofs);
|
||||
for (int i = 1; i < unrolls; i++) {
|
||||
FloatRegister v0_ofs = as_FloatRegister(v0->encoding() + register_stride * i);
|
||||
eor(v0, T16B, v0, v0_ofs);
|
||||
}
|
||||
|
||||
sub(blocks, blocks, (unsigned char)unrolls);
|
||||
|
||||
@ -34,7 +34,7 @@ address RegisterMap::pd_location(VMReg base_reg, int slot_idx) const {
|
||||
// the upper slots by offsetting from the base address.
|
||||
assert(base_reg->is_concrete(), "must pass base reg");
|
||||
int base_reg_enc = (base_reg->value() - ConcreteRegisterImpl::max_gpr) /
|
||||
FloatRegisterImpl::max_slots_per_register;
|
||||
FloatRegister::max_slots_per_register;
|
||||
intptr_t offset_in_bytes = slot_idx * VMRegImpl::stack_slot_size;
|
||||
address base_location = location(base_reg, nullptr);
|
||||
if (base_location != NULL) {
|
||||
|
||||
@ -26,45 +26,36 @@
|
||||
#include "precompiled.hpp"
|
||||
#include "register_aarch64.hpp"
|
||||
|
||||
REGISTER_IMPL_DEFINITION(Register, RegisterImpl, RegisterImpl::number_of_declared_registers);
|
||||
REGISTER_IMPL_DEFINITION(FloatRegister, FloatRegisterImpl, FloatRegisterImpl::number_of_registers);
|
||||
REGISTER_IMPL_DEFINITION(PRegister, PRegisterImpl, PRegisterImpl::number_of_registers);
|
||||
Register::RegisterImpl all_RegisterImpls [Register::number_of_declared_registers + 1];
|
||||
FloatRegister::FloatRegisterImpl all_FloatRegisterImpls[FloatRegister::number_of_registers + 1];
|
||||
PRegister::PRegisterImpl all_PRegisterImpls [PRegister::number_of_registers + 1];
|
||||
|
||||
const int ConcreteRegisterImpl::max_gpr = RegisterImpl::number_of_registers *
|
||||
RegisterImpl::max_slots_per_register;
|
||||
|
||||
const int ConcreteRegisterImpl::max_fpr
|
||||
= ConcreteRegisterImpl::max_gpr +
|
||||
FloatRegisterImpl::number_of_registers * FloatRegisterImpl::max_slots_per_register;
|
||||
|
||||
const int ConcreteRegisterImpl::max_pr
|
||||
= ConcreteRegisterImpl::max_fpr +
|
||||
PRegisterImpl::number_of_registers * PRegisterImpl::max_slots_per_register;
|
||||
|
||||
const char* RegisterImpl::name() const {
|
||||
static const char *const names[number_of_registers] = {
|
||||
const char* Register::RegisterImpl::name() const {
|
||||
static const char *const names[number_of_declared_registers + 1] = {
|
||||
"noreg",
|
||||
"c_rarg0", "c_rarg1", "c_rarg2", "c_rarg3", "c_rarg4", "c_rarg5", "c_rarg6", "c_rarg7",
|
||||
"rscratch1", "rscratch2", "r10", "r11", "r12", "r13", "r14", "r15",
|
||||
"r16", "r17", "r18_tls", "r19", "resp", "rdispatch", "rbcp", "r23",
|
||||
"rlocals", "r25", "rcpool", "rheapbase", "rthread", "rfp", "lr", "sp"
|
||||
"rlocals", "r25", "rcpool", "rheapbase", "rthread", "rfp", "lr", "r31_sp",
|
||||
"zp", "sp"
|
||||
};
|
||||
return is_valid() ? names[encoding()] : "noreg";
|
||||
return names[raw_encoding() + 1];
|
||||
}
|
||||
|
||||
const char* FloatRegisterImpl::name() const {
|
||||
const char* FloatRegister::FloatRegisterImpl::name() const {
|
||||
static const char *const names[number_of_registers] = {
|
||||
"v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7",
|
||||
"v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15",
|
||||
"v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
|
||||
"v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"
|
||||
};
|
||||
return is_valid() ? names[encoding()] : "noreg";
|
||||
return is_valid() ? names[encoding()] : "fnoreg";
|
||||
}
|
||||
|
||||
const char* PRegisterImpl::name() const {
|
||||
const char* PRegister::PRegisterImpl::name() const {
|
||||
static const char *const names[number_of_registers] = {
|
||||
"p0", "p1", "p2", "p3", "p4", "p5", "p6", "p7",
|
||||
"p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15"
|
||||
};
|
||||
return is_valid() ? names[encoding()] : "noreg";
|
||||
return is_valid() ? names[encoding()] : "pnoreg";
|
||||
}
|
||||
|
||||
@ -32,62 +32,87 @@
|
||||
class VMRegImpl;
|
||||
typedef VMRegImpl* VMReg;
|
||||
|
||||
// Use Register as shortcut
|
||||
class RegisterImpl;
|
||||
typedef const RegisterImpl* Register;
|
||||
class Register {
|
||||
private:
|
||||
int _encoding;
|
||||
|
||||
inline constexpr Register as_Register(int encoding);
|
||||
constexpr explicit Register(int encoding) : _encoding(encoding) {}
|
||||
|
||||
class RegisterImpl: public AbstractRegisterImpl {
|
||||
static constexpr Register first();
|
||||
|
||||
public:
|
||||
public:
|
||||
enum {
|
||||
number_of_registers = 32,
|
||||
number_of_declared_registers = 34, // Including SP and ZR.
|
||||
max_slots_per_register = 2
|
||||
number_of_registers = 32,
|
||||
number_of_declared_registers = 34, // Including SP and ZR.
|
||||
max_slots_per_register = 2
|
||||
};
|
||||
|
||||
// derived registers, offsets, and addresses
|
||||
const Register successor() const { return this + 1; }
|
||||
class RegisterImpl: public AbstractRegisterImpl {
|
||||
friend class Register;
|
||||
|
||||
static constexpr const RegisterImpl* first();
|
||||
|
||||
public:
|
||||
// accessors
|
||||
int raw_encoding() const { return this - first(); }
|
||||
int encoding() const { assert(is_valid(), "invalid register"); return raw_encoding(); }
|
||||
bool is_valid() const { return 0 <= raw_encoding() && raw_encoding() < number_of_registers; }
|
||||
|
||||
// derived registers, offsets, and addresses
|
||||
inline Register successor() const;
|
||||
|
||||
VMReg as_VMReg() const;
|
||||
|
||||
const char* name() const;
|
||||
};
|
||||
|
||||
// construction
|
||||
inline friend constexpr Register as_Register(int encoding);
|
||||
|
||||
VMReg as_VMReg() const;
|
||||
constexpr Register() : _encoding(-1) {} // noreg
|
||||
|
||||
// accessors
|
||||
int encoding() const { assert(is_valid(), "invalid register"); return encoding_nocheck(); }
|
||||
bool is_valid() const { return (unsigned)encoding_nocheck() < number_of_registers; }
|
||||
const char* name() const;
|
||||
int encoding_nocheck() const { return this - first(); }
|
||||
int operator==(const Register r) const { return _encoding == r._encoding; }
|
||||
int operator!=(const Register r) const { return _encoding != r._encoding; }
|
||||
|
||||
const RegisterImpl* operator->() const { return RegisterImpl::first() + _encoding; }
|
||||
};
|
||||
|
||||
extern Register::RegisterImpl all_RegisterImpls[Register::number_of_declared_registers + 1] INTERNAL_VISIBILITY;
|
||||
|
||||
REGISTER_IMPL_DECLARATION(Register, RegisterImpl, RegisterImpl::number_of_declared_registers);
|
||||
inline constexpr const Register::RegisterImpl* Register::RegisterImpl::first() {
|
||||
return all_RegisterImpls + 1;
|
||||
}
|
||||
|
||||
// The integer registers of the aarch64 architecture
|
||||
constexpr Register noreg = Register();
|
||||
|
||||
CONSTANT_REGISTER_DECLARATION(Register, noreg, (-1));
|
||||
inline constexpr Register as_Register(int encoding) {
|
||||
if (0 <= encoding && encoding < Register::number_of_declared_registers) {
|
||||
return Register(encoding);
|
||||
}
|
||||
return noreg;
|
||||
}
|
||||
|
||||
CONSTANT_REGISTER_DECLARATION(Register, r0, (0));
|
||||
CONSTANT_REGISTER_DECLARATION(Register, r1, (1));
|
||||
CONSTANT_REGISTER_DECLARATION(Register, r2, (2));
|
||||
CONSTANT_REGISTER_DECLARATION(Register, r3, (3));
|
||||
CONSTANT_REGISTER_DECLARATION(Register, r4, (4));
|
||||
CONSTANT_REGISTER_DECLARATION(Register, r5, (5));
|
||||
CONSTANT_REGISTER_DECLARATION(Register, r6, (6));
|
||||
CONSTANT_REGISTER_DECLARATION(Register, r7, (7));
|
||||
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));
|
||||
CONSTANT_REGISTER_DECLARATION(Register, r16, (16));
|
||||
CONSTANT_REGISTER_DECLARATION(Register, r17, (17));
|
||||
inline Register Register::RegisterImpl::successor() const {
|
||||
assert(is_valid(), "sanity");
|
||||
return as_Register(encoding() + 1);
|
||||
}
|
||||
|
||||
// The integer registers of the AArch64 architecture
|
||||
constexpr Register r0 = as_Register( 0);
|
||||
constexpr Register r1 = as_Register( 1);
|
||||
constexpr Register r2 = as_Register( 2);
|
||||
constexpr Register r3 = as_Register( 3);
|
||||
constexpr Register r4 = as_Register( 4);
|
||||
constexpr Register r5 = as_Register( 5);
|
||||
constexpr Register r6 = as_Register( 6);
|
||||
constexpr Register r7 = as_Register( 7);
|
||||
constexpr Register r8 = as_Register( 8);
|
||||
constexpr Register r9 = as_Register( 9);
|
||||
constexpr Register r10 = as_Register(10);
|
||||
constexpr Register r11 = as_Register(11);
|
||||
constexpr Register r12 = as_Register(12);
|
||||
constexpr Register r13 = as_Register(13);
|
||||
constexpr Register r14 = as_Register(14);
|
||||
constexpr Register r15 = as_Register(15);
|
||||
constexpr Register r16 = as_Register(16);
|
||||
constexpr Register r17 = as_Register(17);
|
||||
|
||||
// In the ABI for Windows+AArch64 the register r18 is used to store the pointer
|
||||
// to the current thread's TEB (where TLS variables are stored). We could
|
||||
@ -99,151 +124,175 @@ CONSTANT_REGISTER_DECLARATION(Register, r17, (17));
|
||||
// It's easier to avoid allocating r18 altogether.
|
||||
//
|
||||
// See https://docs.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions?view=vs-2019#integer-registers
|
||||
CONSTANT_REGISTER_DECLARATION(Register, r18_tls, (18));
|
||||
CONSTANT_REGISTER_DECLARATION(Register, r19, (19));
|
||||
CONSTANT_REGISTER_DECLARATION(Register, r20, (20));
|
||||
CONSTANT_REGISTER_DECLARATION(Register, r21, (21));
|
||||
CONSTANT_REGISTER_DECLARATION(Register, r22, (22));
|
||||
CONSTANT_REGISTER_DECLARATION(Register, r23, (23));
|
||||
CONSTANT_REGISTER_DECLARATION(Register, r24, (24));
|
||||
CONSTANT_REGISTER_DECLARATION(Register, r25, (25));
|
||||
CONSTANT_REGISTER_DECLARATION(Register, r26, (26));
|
||||
CONSTANT_REGISTER_DECLARATION(Register, r27, (27));
|
||||
CONSTANT_REGISTER_DECLARATION(Register, r28, (28));
|
||||
CONSTANT_REGISTER_DECLARATION(Register, r29, (29));
|
||||
CONSTANT_REGISTER_DECLARATION(Register, r30, (30));
|
||||
constexpr Register r18_tls = as_Register(18);
|
||||
constexpr Register r19 = as_Register(19);
|
||||
constexpr Register r20 = as_Register(20);
|
||||
constexpr Register r21 = as_Register(21);
|
||||
constexpr Register r22 = as_Register(22);
|
||||
constexpr Register r23 = as_Register(23);
|
||||
constexpr Register r24 = as_Register(24);
|
||||
constexpr Register r25 = as_Register(25);
|
||||
constexpr Register r26 = as_Register(26);
|
||||
constexpr Register r27 = as_Register(27);
|
||||
constexpr Register r28 = as_Register(28);
|
||||
constexpr Register r29 = as_Register(29);
|
||||
constexpr Register r30 = as_Register(30);
|
||||
|
||||
|
||||
// r31 is not a general purpose register, but represents either the
|
||||
// stack pointer or the zero/discard register depending on the
|
||||
// instruction.
|
||||
CONSTANT_REGISTER_DECLARATION(Register, r31_sp, (31));
|
||||
CONSTANT_REGISTER_DECLARATION(Register, zr, (32));
|
||||
CONSTANT_REGISTER_DECLARATION(Register, sp, (33));
|
||||
constexpr Register r31_sp = as_Register(31);
|
||||
constexpr Register zr = as_Register(32);
|
||||
constexpr Register sp = as_Register(33);
|
||||
|
||||
// Used as a filler in instructions where a register field is unused.
|
||||
const Register dummy_reg = r31_sp;
|
||||
constexpr Register dummy_reg = r31_sp;
|
||||
|
||||
// Use FloatRegister as shortcut
|
||||
class FloatRegisterImpl;
|
||||
typedef const FloatRegisterImpl* FloatRegister;
|
||||
|
||||
inline constexpr FloatRegister as_FloatRegister(int encoding);
|
||||
|
||||
// The implementation of floating point registers for the architecture
|
||||
class FloatRegisterImpl: public AbstractRegisterImpl {
|
||||
static constexpr FloatRegister first();
|
||||
class FloatRegister {
|
||||
private:
|
||||
int _encoding;
|
||||
|
||||
constexpr explicit FloatRegister(int encoding) : _encoding(encoding) {}
|
||||
|
||||
public:
|
||||
inline friend constexpr FloatRegister as_FloatRegister(int encoding);
|
||||
|
||||
public:
|
||||
enum {
|
||||
number_of_registers = 32,
|
||||
max_slots_per_register = 4,
|
||||
save_slots_per_register = 2,
|
||||
slots_per_neon_register = 4,
|
||||
number_of_registers = 32,
|
||||
max_slots_per_register = 4,
|
||||
save_slots_per_register = 2,
|
||||
slots_per_neon_register = 4,
|
||||
extra_save_slots_per_neon_register = slots_per_neon_register - save_slots_per_register
|
||||
};
|
||||
|
||||
// construction
|
||||
inline friend constexpr FloatRegister as_FloatRegister(int encoding);
|
||||
class FloatRegisterImpl: public AbstractRegisterImpl {
|
||||
friend class FloatRegister;
|
||||
|
||||
VMReg as_VMReg() const;
|
||||
static constexpr const FloatRegisterImpl* first();
|
||||
|
||||
// derived registers, offsets, and addresses
|
||||
FloatRegister successor() const {
|
||||
return as_FloatRegister((encoding() + 1) % (unsigned)number_of_registers);
|
||||
}
|
||||
public:
|
||||
// accessors
|
||||
int raw_encoding() const { return this - first(); }
|
||||
int encoding() const { assert(is_valid(), "invalid register"); return raw_encoding(); }
|
||||
bool is_valid() const { return 0 <= raw_encoding() && raw_encoding() < number_of_registers; }
|
||||
|
||||
// accessors
|
||||
int encoding() const { assert(is_valid(), "invalid register"); return encoding_nocheck(); }
|
||||
bool is_valid() const { return (unsigned)encoding_nocheck() < number_of_registers; }
|
||||
const char* name() const;
|
||||
int encoding_nocheck() const { return this - first(); }
|
||||
// derived registers, offsets, and addresses
|
||||
inline FloatRegister successor() const;
|
||||
|
||||
VMReg as_VMReg() const;
|
||||
|
||||
const char* name() const;
|
||||
};
|
||||
|
||||
constexpr FloatRegister() : _encoding(-1) {} // fnoreg
|
||||
|
||||
int operator==(const FloatRegister r) const { return _encoding == r._encoding; }
|
||||
int operator!=(const FloatRegister r) const { return _encoding != r._encoding; }
|
||||
|
||||
const FloatRegisterImpl* operator->() const { return FloatRegisterImpl::first() + _encoding; }
|
||||
};
|
||||
|
||||
REGISTER_IMPL_DECLARATION(FloatRegister, FloatRegisterImpl, FloatRegisterImpl::number_of_registers);
|
||||
extern FloatRegister::FloatRegisterImpl all_FloatRegisterImpls[FloatRegister::number_of_registers + 1] INTERNAL_VISIBILITY;
|
||||
|
||||
inline constexpr const FloatRegister::FloatRegisterImpl* FloatRegister::FloatRegisterImpl::first() {
|
||||
return all_FloatRegisterImpls + 1;
|
||||
}
|
||||
|
||||
// The float registers of the AARCH64 architecture
|
||||
constexpr FloatRegister fnoreg = FloatRegister();
|
||||
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, fnoreg , (-1));
|
||||
inline constexpr FloatRegister as_FloatRegister(int encoding) {
|
||||
if (0 <= encoding && encoding < FloatRegister::number_of_registers) {
|
||||
return FloatRegister(encoding);
|
||||
}
|
||||
return fnoreg;
|
||||
}
|
||||
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, v0 , ( 0));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, v1 , ( 1));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, v2 , ( 2));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, v3 , ( 3));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, v4 , ( 4));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, v5 , ( 5));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, v6 , ( 6));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, v7 , ( 7));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, v8 , ( 8));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, v9 , ( 9));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, v10 , (10));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, v11 , (11));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, v12 , (12));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, v13 , (13));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, v14 , (14));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, v15 , (15));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, v16 , (16));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, v17 , (17));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, v18 , (18));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, v19 , (19));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, v20 , (20));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, v21 , (21));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, v22 , (22));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, v23 , (23));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, v24 , (24));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, v25 , (25));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, v26 , (26));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, v27 , (27));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, v28 , (28));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, v29 , (29));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, v30 , (30));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, v31 , (31));
|
||||
inline FloatRegister FloatRegister::FloatRegisterImpl::successor() const {
|
||||
assert(is_valid(), "sanity");
|
||||
return as_FloatRegister((encoding() + 1) % number_of_registers);
|
||||
}
|
||||
|
||||
// The float registers of the AArch64 architecture
|
||||
constexpr FloatRegister v0 = as_FloatRegister( 0);
|
||||
constexpr FloatRegister v1 = as_FloatRegister( 1);
|
||||
constexpr FloatRegister v2 = as_FloatRegister( 2);
|
||||
constexpr FloatRegister v3 = as_FloatRegister( 3);
|
||||
constexpr FloatRegister v4 = as_FloatRegister( 4);
|
||||
constexpr FloatRegister v5 = as_FloatRegister( 5);
|
||||
constexpr FloatRegister v6 = as_FloatRegister( 6);
|
||||
constexpr FloatRegister v7 = as_FloatRegister( 7);
|
||||
constexpr FloatRegister v8 = as_FloatRegister( 8);
|
||||
constexpr FloatRegister v9 = as_FloatRegister( 9);
|
||||
constexpr FloatRegister v10 = as_FloatRegister(10);
|
||||
constexpr FloatRegister v11 = as_FloatRegister(11);
|
||||
constexpr FloatRegister v12 = as_FloatRegister(12);
|
||||
constexpr FloatRegister v13 = as_FloatRegister(13);
|
||||
constexpr FloatRegister v14 = as_FloatRegister(14);
|
||||
constexpr FloatRegister v15 = as_FloatRegister(15);
|
||||
constexpr FloatRegister v16 = as_FloatRegister(16);
|
||||
constexpr FloatRegister v17 = as_FloatRegister(17);
|
||||
constexpr FloatRegister v18 = as_FloatRegister(18);
|
||||
constexpr FloatRegister v19 = as_FloatRegister(19);
|
||||
constexpr FloatRegister v20 = as_FloatRegister(20);
|
||||
constexpr FloatRegister v21 = as_FloatRegister(21);
|
||||
constexpr FloatRegister v22 = as_FloatRegister(22);
|
||||
constexpr FloatRegister v23 = as_FloatRegister(23);
|
||||
constexpr FloatRegister v24 = as_FloatRegister(24);
|
||||
constexpr FloatRegister v25 = as_FloatRegister(25);
|
||||
constexpr FloatRegister v26 = as_FloatRegister(26);
|
||||
constexpr FloatRegister v27 = as_FloatRegister(27);
|
||||
constexpr FloatRegister v28 = as_FloatRegister(28);
|
||||
constexpr FloatRegister v29 = as_FloatRegister(29);
|
||||
constexpr FloatRegister v30 = as_FloatRegister(30);
|
||||
constexpr FloatRegister v31 = as_FloatRegister(31);
|
||||
|
||||
// SVE vector registers, shared with the SIMD&FP v0-v31. Vn maps to Zn[127:0].
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, z0 , ( 0));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, z1 , ( 1));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, z2 , ( 2));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, z3 , ( 3));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, z4 , ( 4));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, z5 , ( 5));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, z6 , ( 6));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, z7 , ( 7));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, z8 , ( 8));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, z9 , ( 9));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, z10 , (10));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, z11 , (11));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, z12 , (12));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, z13 , (13));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, z14 , (14));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, z15 , (15));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, z16 , (16));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, z17 , (17));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, z18 , (18));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, z19 , (19));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, z20 , (20));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, z21 , (21));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, z22 , (22));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, z23 , (23));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, z24 , (24));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, z25 , (25));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, z26 , (26));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, z27 , (27));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, z28 , (28));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, z29 , (29));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, z30 , (30));
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, z31 , (31));
|
||||
constexpr FloatRegister z0 = v0;
|
||||
constexpr FloatRegister z1 = v1;
|
||||
constexpr FloatRegister z2 = v2;
|
||||
constexpr FloatRegister z3 = v3;
|
||||
constexpr FloatRegister z4 = v4;
|
||||
constexpr FloatRegister z5 = v5;
|
||||
constexpr FloatRegister z6 = v6;
|
||||
constexpr FloatRegister z7 = v7;
|
||||
constexpr FloatRegister z8 = v8;
|
||||
constexpr FloatRegister z9 = v9;
|
||||
constexpr FloatRegister z10 = v10;
|
||||
constexpr FloatRegister z11 = v11;
|
||||
constexpr FloatRegister z12 = v12;
|
||||
constexpr FloatRegister z13 = v13;
|
||||
constexpr FloatRegister z14 = v14;
|
||||
constexpr FloatRegister z15 = v15;
|
||||
constexpr FloatRegister z16 = v16;
|
||||
constexpr FloatRegister z17 = v17;
|
||||
constexpr FloatRegister z18 = v18;
|
||||
constexpr FloatRegister z19 = v19;
|
||||
constexpr FloatRegister z20 = v20;
|
||||
constexpr FloatRegister z21 = v21;
|
||||
constexpr FloatRegister z22 = v22;
|
||||
constexpr FloatRegister z23 = v23;
|
||||
constexpr FloatRegister z24 = v24;
|
||||
constexpr FloatRegister z25 = v25;
|
||||
constexpr FloatRegister z26 = v26;
|
||||
constexpr FloatRegister z27 = v27;
|
||||
constexpr FloatRegister z28 = v28;
|
||||
constexpr FloatRegister z29 = v29;
|
||||
constexpr FloatRegister z30 = v30;
|
||||
constexpr FloatRegister z31 = v31;
|
||||
|
||||
|
||||
class PRegisterImpl;
|
||||
typedef const PRegisterImpl* PRegister;
|
||||
inline constexpr PRegister as_PRegister(int encoding);
|
||||
|
||||
// The implementation of predicate registers for the architecture
|
||||
class PRegisterImpl: public AbstractRegisterImpl {
|
||||
static constexpr PRegister first();
|
||||
class PRegister {
|
||||
int _encoding;
|
||||
|
||||
constexpr explicit PRegister(int encoding) : _encoding(encoding) {}
|
||||
|
||||
public:
|
||||
inline friend constexpr PRegister as_PRegister(int encoding);
|
||||
|
||||
public:
|
||||
enum {
|
||||
number_of_registers = 16,
|
||||
number_of_governing_registers = 8,
|
||||
@ -255,66 +304,87 @@ class PRegisterImpl: public AbstractRegisterImpl {
|
||||
max_slots_per_register = 1
|
||||
};
|
||||
|
||||
// construction
|
||||
inline friend constexpr PRegister as_PRegister(int encoding);
|
||||
constexpr PRegister() : _encoding(-1) {} // pnoreg
|
||||
|
||||
VMReg as_VMReg() const;
|
||||
class PRegisterImpl: public AbstractRegisterImpl {
|
||||
friend class PRegister;
|
||||
|
||||
// derived registers, offsets, and addresses
|
||||
PRegister successor() const { return this + 1; }
|
||||
static constexpr const PRegisterImpl* first();
|
||||
|
||||
// accessors
|
||||
int encoding() const { assert(is_valid(), "invalid register"); return encoding_nocheck(); }
|
||||
int encoding_nocheck() const { return this - first(); }
|
||||
bool is_valid() const { return (unsigned)encoding_nocheck() < number_of_registers; }
|
||||
bool is_governing() const { return first() <= this && this - first() < number_of_governing_registers; }
|
||||
const char* name() const;
|
||||
public:
|
||||
// accessors
|
||||
int raw_encoding() const { return this - first(); }
|
||||
int encoding() const { assert(is_valid(), "invalid register"); return raw_encoding(); }
|
||||
bool is_valid() const { return 0 <= raw_encoding() && raw_encoding() < number_of_registers; }
|
||||
bool is_governing() const { return 0 <= raw_encoding() && raw_encoding() < number_of_governing_registers; }
|
||||
|
||||
// derived registers, offsets, and addresses
|
||||
inline PRegister successor() const;
|
||||
|
||||
VMReg as_VMReg() const;
|
||||
|
||||
const char* name() const;
|
||||
};
|
||||
|
||||
int operator==(const PRegister r) const { return _encoding == r._encoding; }
|
||||
int operator!=(const PRegister r) const { return _encoding != r._encoding; }
|
||||
|
||||
const PRegisterImpl* operator->() const { return PRegisterImpl::first() + _encoding; }
|
||||
};
|
||||
|
||||
extern PRegister::PRegisterImpl all_PRegisterImpls[PRegister::number_of_registers + 1] INTERNAL_VISIBILITY;
|
||||
|
||||
REGISTER_IMPL_DECLARATION(PRegister, PRegisterImpl, PRegisterImpl::number_of_registers);
|
||||
inline constexpr const PRegister::PRegisterImpl* PRegister::PRegisterImpl::first() {
|
||||
return all_PRegisterImpls + 1;
|
||||
}
|
||||
|
||||
constexpr PRegister pnoreg = PRegister();
|
||||
|
||||
inline constexpr PRegister as_PRegister(int encoding) {
|
||||
if (0 <= encoding && encoding < PRegister::number_of_registers) {
|
||||
return PRegister(encoding);
|
||||
}
|
||||
return pnoreg;
|
||||
}
|
||||
|
||||
inline PRegister PRegister::PRegisterImpl::successor() const {
|
||||
assert(is_valid(), "sanity");
|
||||
return as_PRegister(encoding() + 1);
|
||||
}
|
||||
|
||||
// The predicate registers of SVE.
|
||||
//
|
||||
CONSTANT_REGISTER_DECLARATION(PRegister, pnoreg, (-1));
|
||||
|
||||
CONSTANT_REGISTER_DECLARATION(PRegister, p0, ( 0));
|
||||
CONSTANT_REGISTER_DECLARATION(PRegister, p1, ( 1));
|
||||
CONSTANT_REGISTER_DECLARATION(PRegister, p2, ( 2));
|
||||
CONSTANT_REGISTER_DECLARATION(PRegister, p3, ( 3));
|
||||
CONSTANT_REGISTER_DECLARATION(PRegister, p4, ( 4));
|
||||
CONSTANT_REGISTER_DECLARATION(PRegister, p5, ( 5));
|
||||
CONSTANT_REGISTER_DECLARATION(PRegister, p6, ( 6));
|
||||
CONSTANT_REGISTER_DECLARATION(PRegister, p7, ( 7));
|
||||
CONSTANT_REGISTER_DECLARATION(PRegister, p8, ( 8));
|
||||
CONSTANT_REGISTER_DECLARATION(PRegister, p9, ( 9));
|
||||
CONSTANT_REGISTER_DECLARATION(PRegister, p10, (10));
|
||||
CONSTANT_REGISTER_DECLARATION(PRegister, p11, (11));
|
||||
CONSTANT_REGISTER_DECLARATION(PRegister, p12, (12));
|
||||
CONSTANT_REGISTER_DECLARATION(PRegister, p13, (13));
|
||||
CONSTANT_REGISTER_DECLARATION(PRegister, p14, (14));
|
||||
CONSTANT_REGISTER_DECLARATION(PRegister, p15, (15));
|
||||
constexpr PRegister p0 = as_PRegister( 0);
|
||||
constexpr PRegister p1 = as_PRegister( 1);
|
||||
constexpr PRegister p2 = as_PRegister( 2);
|
||||
constexpr PRegister p3 = as_PRegister( 3);
|
||||
constexpr PRegister p4 = as_PRegister( 4);
|
||||
constexpr PRegister p5 = as_PRegister( 5);
|
||||
constexpr PRegister p6 = as_PRegister( 6);
|
||||
constexpr PRegister p7 = as_PRegister( 7);
|
||||
constexpr PRegister p8 = as_PRegister( 8);
|
||||
constexpr PRegister p9 = as_PRegister( 9);
|
||||
constexpr PRegister p10 = as_PRegister(10);
|
||||
constexpr PRegister p11 = as_PRegister(11);
|
||||
constexpr PRegister p12 = as_PRegister(12);
|
||||
constexpr PRegister p13 = as_PRegister(13);
|
||||
constexpr PRegister p14 = as_PRegister(14);
|
||||
constexpr PRegister p15 = as_PRegister(15);
|
||||
|
||||
// Need to know the total number of registers of all sorts for SharedInfo.
|
||||
// Define a class that exports it.
|
||||
class ConcreteRegisterImpl : public AbstractRegisterImpl {
|
||||
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.
|
||||
max_gpr = Register::number_of_registers * Register::max_slots_per_register,
|
||||
max_fpr = max_gpr + FloatRegister::number_of_registers * FloatRegister::max_slots_per_register,
|
||||
max_pr = max_fpr + PRegister::number_of_registers * PRegister::max_slots_per_register,
|
||||
|
||||
number_of_registers = (RegisterImpl::max_slots_per_register * RegisterImpl::number_of_registers +
|
||||
FloatRegisterImpl::max_slots_per_register * FloatRegisterImpl::number_of_registers +
|
||||
PRegisterImpl::max_slots_per_register * PRegisterImpl::number_of_registers +
|
||||
1) // flags
|
||||
// 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 = max_pr + 1 // gpr/fpr/pr + flags
|
||||
};
|
||||
|
||||
// added to make it compile
|
||||
static const int max_gpr;
|
||||
static const int max_fpr;
|
||||
static const int max_pr;
|
||||
};
|
||||
|
||||
typedef AbstractRegSet<Register> RegSet;
|
||||
|
||||
@ -120,9 +120,9 @@ class RegisterSaver {
|
||||
// setting for it. We must therefore force the layout
|
||||
// so that it agrees with the frame sender code.
|
||||
r0_off = fpu_state_off + FPUStateSizeInWords,
|
||||
rfp_off = r0_off + (RegisterImpl::number_of_registers - 2) * RegisterImpl::max_slots_per_register,
|
||||
return_off = rfp_off + RegisterImpl::max_slots_per_register, // slot for return address
|
||||
reg_save_size = return_off + RegisterImpl::max_slots_per_register};
|
||||
rfp_off = r0_off + (Register::number_of_registers - 2) * Register::max_slots_per_register,
|
||||
return_off = rfp_off + Register::max_slots_per_register, // slot for return address
|
||||
reg_save_size = return_off + Register::max_slots_per_register};
|
||||
|
||||
};
|
||||
|
||||
@ -132,11 +132,11 @@ int RegisterSaver::reg_offset_in_bytes(Register r) {
|
||||
// offset depends on whether we are saving full vectors, and whether
|
||||
// those vectors are NEON or SVE.
|
||||
|
||||
int slots_per_vect = FloatRegisterImpl::save_slots_per_register;
|
||||
int slots_per_vect = FloatRegister::save_slots_per_register;
|
||||
|
||||
#if COMPILER2_OR_JVMCI
|
||||
if (_save_vectors) {
|
||||
slots_per_vect = FloatRegisterImpl::slots_per_neon_register;
|
||||
slots_per_vect = FloatRegister::slots_per_neon_register;
|
||||
|
||||
#ifdef COMPILER2
|
||||
if (Matcher::supports_scalable_vector()) {
|
||||
@ -146,7 +146,7 @@ int RegisterSaver::reg_offset_in_bytes(Register r) {
|
||||
}
|
||||
#endif
|
||||
|
||||
int r0_offset = v0_offset_in_bytes() + (slots_per_vect * FloatRegisterImpl::number_of_registers) * BytesPerInt;
|
||||
int r0_offset = v0_offset_in_bytes() + (slots_per_vect * FloatRegister::number_of_registers) * BytesPerInt;
|
||||
return r0_offset + r->encoding() * wordSize;
|
||||
}
|
||||
|
||||
@ -164,7 +164,7 @@ int RegisterSaver::total_sve_predicate_in_bytes() {
|
||||
// of 16 bytes so we manually align it up.
|
||||
return align_up(Matcher::scalable_predicate_reg_slots() *
|
||||
VMRegImpl::stack_slot_size *
|
||||
PRegisterImpl::number_of_saved_registers, 16);
|
||||
PRegister::number_of_saved_registers, 16);
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
@ -192,13 +192,13 @@ OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_
|
||||
int extra_save_slots_per_register = 0;
|
||||
// Save upper half of vector registers
|
||||
if (use_sve) {
|
||||
extra_save_slots_per_register = sve_vector_size_in_slots - FloatRegisterImpl::save_slots_per_register;
|
||||
extra_save_slots_per_register = sve_vector_size_in_slots - FloatRegister::save_slots_per_register;
|
||||
} else {
|
||||
extra_save_slots_per_register = FloatRegisterImpl::extra_save_slots_per_neon_register;
|
||||
extra_save_slots_per_register = FloatRegister::extra_save_slots_per_neon_register;
|
||||
}
|
||||
int extra_vector_bytes = extra_save_slots_per_register *
|
||||
VMRegImpl::stack_slot_size *
|
||||
FloatRegisterImpl::number_of_registers;
|
||||
FloatRegister::number_of_registers;
|
||||
additional_frame_words += ((extra_vector_bytes + total_predicate_in_bytes) / wordSize);
|
||||
}
|
||||
#else
|
||||
@ -227,31 +227,31 @@ OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_
|
||||
OopMapSet *oop_maps = new OopMapSet();
|
||||
OopMap* oop_map = new OopMap(frame_size_in_slots, 0);
|
||||
|
||||
for (int i = 0; i < RegisterImpl::number_of_registers; i++) {
|
||||
for (int i = 0; i < Register::number_of_registers; i++) {
|
||||
Register r = as_Register(i);
|
||||
if (r <= rfp && r != rscratch1 && r != rscratch2) {
|
||||
if (i <= rfp->encoding() && r != rscratch1 && r != rscratch2) {
|
||||
// SP offsets are in 4-byte words.
|
||||
// Register slots are 8 bytes wide, 32 floating-point registers.
|
||||
int sp_offset = RegisterImpl::max_slots_per_register * i +
|
||||
FloatRegisterImpl::save_slots_per_register * FloatRegisterImpl::number_of_registers;
|
||||
int sp_offset = Register::max_slots_per_register * i +
|
||||
FloatRegister::save_slots_per_register * FloatRegister::number_of_registers;
|
||||
oop_map->set_callee_saved(VMRegImpl::stack2reg(sp_offset + additional_frame_slots), r->as_VMReg());
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < FloatRegisterImpl::number_of_registers; i++) {
|
||||
for (int i = 0; i < FloatRegister::number_of_registers; i++) {
|
||||
FloatRegister r = as_FloatRegister(i);
|
||||
int sp_offset = 0;
|
||||
if (_save_vectors) {
|
||||
sp_offset = use_sve ? (total_predicate_in_slots + sve_vector_size_in_slots * i) :
|
||||
(FloatRegisterImpl::slots_per_neon_register * i);
|
||||
(FloatRegister::slots_per_neon_register * i);
|
||||
} else {
|
||||
sp_offset = FloatRegisterImpl::save_slots_per_register * i;
|
||||
sp_offset = FloatRegister::save_slots_per_register * i;
|
||||
}
|
||||
oop_map->set_callee_saved(VMRegImpl::stack2reg(sp_offset), r->as_VMReg());
|
||||
}
|
||||
|
||||
if (_save_vectors && use_sve) {
|
||||
for (int i = 0; i < PRegisterImpl::number_of_saved_registers; i++) {
|
||||
for (int i = 0; i < PRegister::number_of_saved_registers; i++) {
|
||||
PRegister r = as_PRegister(i);
|
||||
int sp_offset = sve_predicate_size_in_slots * i;
|
||||
oop_map->set_callee_saved(VMRegImpl::stack2reg(sp_offset), r->as_VMReg());
|
||||
@ -290,8 +290,8 @@ bool SharedRuntime::is_wide_vector(int size) {
|
||||
// refer to 4-byte stack slots. All stack slots are based off of the stack pointer
|
||||
// as framesizes are fixed.
|
||||
// VMRegImpl::stack0 refers to the first slot 0(sp).
|
||||
// and VMRegImpl::stack0+1 refers to the memory word 4-byes higher. Register
|
||||
// up to RegisterImpl::number_of_registers) are the 64-bit
|
||||
// and VMRegImpl::stack0+1 refers to the memory word 4-byes higher.
|
||||
// Register up to Register::number_of_registers are the 64-bit
|
||||
// integer registers.
|
||||
|
||||
// Note: the INPUTS in sig_bt are in units of Java argument words,
|
||||
@ -1469,12 +1469,12 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
||||
int int_args = 0;
|
||||
|
||||
#ifdef ASSERT
|
||||
bool reg_destroyed[RegisterImpl::number_of_registers];
|
||||
bool freg_destroyed[FloatRegisterImpl::number_of_registers];
|
||||
for ( int r = 0 ; r < RegisterImpl::number_of_registers ; r++ ) {
|
||||
bool reg_destroyed[Register::number_of_registers];
|
||||
bool freg_destroyed[FloatRegister::number_of_registers];
|
||||
for ( int r = 0 ; r < Register::number_of_registers ; r++ ) {
|
||||
reg_destroyed[r] = false;
|
||||
}
|
||||
for ( int f = 0 ; f < FloatRegisterImpl::number_of_registers ; f++ ) {
|
||||
for ( int f = 0 ; f < FloatRegister::number_of_registers ; f++ ) {
|
||||
freg_destroyed[f] = false;
|
||||
}
|
||||
|
||||
|
||||
@ -3045,8 +3045,9 @@ class StubGenerator: public StubCodeGenerator {
|
||||
__ movi(v9, __ T4S, 1);
|
||||
__ ins(v8, __ S, v9, 3, 3); // v8 contains { 0, 0, 0, 1 }
|
||||
|
||||
for (FloatRegister f = v0; f < v0 + bulk_width; f++) {
|
||||
__ rev32(f, __ T16B, v16);
|
||||
for (int i = 0; i < bulk_width; i++) {
|
||||
FloatRegister v0_ofs = as_FloatRegister(v0->encoding() + i);
|
||||
__ rev32(v0_ofs, __ T16B, v16);
|
||||
__ addv(v16, __ T4S, v16, v8);
|
||||
}
|
||||
|
||||
@ -3061,7 +3062,9 @@ class StubGenerator: public StubCodeGenerator {
|
||||
|
||||
// XOR the encrypted counters with the inputs
|
||||
for (int i = 0; i < bulk_width; i++) {
|
||||
__ eor(v0 + i, __ T16B, v0 + i, v8 + i);
|
||||
FloatRegister v0_ofs = as_FloatRegister(v0->encoding() + i);
|
||||
FloatRegister v8_ofs = as_FloatRegister(v8->encoding() + i);
|
||||
__ eor(v0_ofs, __ T16B, v0_ofs, v8_ofs);
|
||||
}
|
||||
|
||||
// Write the encrypted data
|
||||
@ -3162,7 +3165,10 @@ class StubGenerator: public StubCodeGenerator {
|
||||
__ movi(v8, __ T4S, 0);
|
||||
__ movi(v9, __ T4S, 1);
|
||||
__ ins(v8, __ S, v9, 3, 3); // v8 contains { 0, 0, 0, 1 }
|
||||
for (FloatRegister f = v0; f < v8; f++) {
|
||||
|
||||
assert(v0->encoding() < v8->encoding(), "");
|
||||
for (int i = v0->encoding(); i < v8->encoding(); i++) {
|
||||
FloatRegister f = as_FloatRegister(i);
|
||||
__ rev32(f, __ T16B, v16);
|
||||
__ addv(v16, __ T4S, v16, v8);
|
||||
}
|
||||
@ -3176,7 +3182,9 @@ class StubGenerator: public StubCodeGenerator {
|
||||
|
||||
// XOR the encrypted counters with the inputs
|
||||
for (int i = 0; i < 8; i++) {
|
||||
__ eor(v0 + i, __ T16B, v0 + i, v8 + i);
|
||||
FloatRegister v0_ofs = as_FloatRegister(v0->encoding() + i);
|
||||
FloatRegister v8_ofs = as_FloatRegister(v8->encoding() + i);
|
||||
__ eor(v0_ofs, __ T16B, v0_ofs, v8_ofs);
|
||||
}
|
||||
__ st1(v0, v1, v2, v3, __ T16B, __ post(out, 4 * 16));
|
||||
__ st1(v4, v5, v6, v7, __ T16B, __ post(out, 4 * 16));
|
||||
@ -7246,7 +7254,8 @@ class StubGenerator: public StubCodeGenerator {
|
||||
// Preserves len
|
||||
// Leaves s pointing to the address which was in d at start
|
||||
void reverse(Register d, Register s, Register len, Register tmp1, Register tmp2) {
|
||||
assert(tmp1 < r19 && tmp2 < r19, "register corruption");
|
||||
assert(tmp1->encoding() < r19->encoding(), "register corruption");
|
||||
assert(tmp2->encoding() < r19->encoding(), "register corruption");
|
||||
|
||||
lea(s, Address(s, len, Address::uxtw(LogBytesPerWord)));
|
||||
mov(tmp1, len);
|
||||
|
||||
@ -39,7 +39,7 @@
|
||||
// for callee saved regs, according to the caller's ABI
|
||||
static int compute_reg_save_area_size(const ABIDescriptor& abi) {
|
||||
int size = 0;
|
||||
for (int i = 0; i < RegisterImpl::number_of_registers; i++) {
|
||||
for (int i = 0; i < Register::number_of_registers; i++) {
|
||||
Register reg = as_Register(i);
|
||||
if (reg == rfp || reg == sp) continue; // saved/restored by prologue/epilogue
|
||||
if (!abi.is_volatile_reg(reg)) {
|
||||
@ -47,7 +47,7 @@ static int compute_reg_save_area_size(const ABIDescriptor& abi) {
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < FloatRegisterImpl::number_of_registers; i++) {
|
||||
for (int i = 0; i < FloatRegister::number_of_registers; i++) {
|
||||
FloatRegister reg = as_FloatRegister(i);
|
||||
if (!abi.is_volatile_reg(reg)) {
|
||||
// Only the lower 64 bits of vector registers need to be preserved.
|
||||
@ -66,7 +66,7 @@ static void preserve_callee_saved_registers(MacroAssembler* _masm, const ABIDesc
|
||||
int offset = reg_save_area_offset;
|
||||
|
||||
__ block_comment("{ preserve_callee_saved_regs ");
|
||||
for (int i = 0; i < RegisterImpl::number_of_registers; i++) {
|
||||
for (int i = 0; i < Register::number_of_registers; i++) {
|
||||
Register reg = as_Register(i);
|
||||
if (reg == rfp || reg == sp) continue; // saved/restored by prologue/epilogue
|
||||
if (!abi.is_volatile_reg(reg)) {
|
||||
@ -75,7 +75,7 @@ static void preserve_callee_saved_registers(MacroAssembler* _masm, const ABIDesc
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < FloatRegisterImpl::number_of_registers; i++) {
|
||||
for (int i = 0; i < FloatRegister::number_of_registers; i++) {
|
||||
FloatRegister reg = as_FloatRegister(i);
|
||||
if (!abi.is_volatile_reg(reg)) {
|
||||
__ strd(reg, Address(sp, offset));
|
||||
@ -94,7 +94,7 @@ static void restore_callee_saved_registers(MacroAssembler* _masm, const ABIDescr
|
||||
int offset = reg_save_area_offset;
|
||||
|
||||
__ block_comment("{ restore_callee_saved_regs ");
|
||||
for (int i = 0; i < RegisterImpl::number_of_registers; i++) {
|
||||
for (int i = 0; i < Register::number_of_registers; i++) {
|
||||
Register reg = as_Register(i);
|
||||
if (reg == rfp || reg == sp) continue; // saved/restored by prologue/epilogue
|
||||
if (!abi.is_volatile_reg(reg)) {
|
||||
@ -103,7 +103,7 @@ static void restore_callee_saved_registers(MacroAssembler* _masm, const ABIDescr
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < FloatRegisterImpl::number_of_registers; i++) {
|
||||
for (int i = 0; i < FloatRegister::number_of_registers; i++) {
|
||||
FloatRegister reg = as_FloatRegister(i);
|
||||
if (!abi.is_volatile_reg(reg)) {
|
||||
__ ldrd(reg, Address(sp, offset));
|
||||
|
||||
@ -33,7 +33,7 @@ void VMRegImpl::set_regName() {
|
||||
Register reg = ::as_Register(0);
|
||||
int i;
|
||||
for (i = 0; i < ConcreteRegisterImpl::max_gpr ; ) {
|
||||
for (int j = 0 ; j < RegisterImpl::max_slots_per_register ; j++) {
|
||||
for (int j = 0 ; j < Register::max_slots_per_register ; j++) {
|
||||
regName[i++] = reg->name();
|
||||
}
|
||||
reg = reg->successor();
|
||||
@ -41,7 +41,7 @@ void VMRegImpl::set_regName() {
|
||||
|
||||
FloatRegister freg = ::as_FloatRegister(0);
|
||||
for ( ; i < ConcreteRegisterImpl::max_fpr ; ) {
|
||||
for (int j = 0 ; j < FloatRegisterImpl::max_slots_per_register ; j++) {
|
||||
for (int j = 0 ; j < FloatRegister::max_slots_per_register ; j++) {
|
||||
regName[i++] = freg->name();
|
||||
}
|
||||
freg = freg->successor();
|
||||
|
||||
@ -41,27 +41,27 @@ inline bool is_PRegister() {
|
||||
inline Register as_Register() {
|
||||
assert( is_Register(), "must be");
|
||||
// Yuk
|
||||
return ::as_Register(value() / RegisterImpl::max_slots_per_register);
|
||||
return ::as_Register(value() / Register::max_slots_per_register);
|
||||
}
|
||||
|
||||
inline FloatRegister as_FloatRegister() {
|
||||
assert( is_FloatRegister() && is_even(value()), "must be" );
|
||||
// Yuk
|
||||
return ::as_FloatRegister((value() - ConcreteRegisterImpl::max_gpr) /
|
||||
FloatRegisterImpl::max_slots_per_register);
|
||||
FloatRegister::max_slots_per_register);
|
||||
}
|
||||
|
||||
inline PRegister as_PRegister() {
|
||||
assert( is_PRegister(), "must be" );
|
||||
return ::as_PRegister((value() - ConcreteRegisterImpl::max_fpr) /
|
||||
PRegisterImpl::max_slots_per_register);
|
||||
PRegister::max_slots_per_register);
|
||||
}
|
||||
|
||||
inline bool is_concrete() {
|
||||
assert(is_reg(), "must be");
|
||||
if (is_FloatRegister()) {
|
||||
int base = value() - ConcreteRegisterImpl::max_gpr;
|
||||
return base % FloatRegisterImpl::max_slots_per_register == 0;
|
||||
return (base % FloatRegister::max_slots_per_register) == 0;
|
||||
} else if (is_PRegister()) {
|
||||
return true; // Single slot
|
||||
} else {
|
||||
|
||||
@ -26,18 +26,18 @@
|
||||
#ifndef CPU_AARCH64_VMREG_AARCH64_INLINE_HPP
|
||||
#define CPU_AARCH64_VMREG_AARCH64_INLINE_HPP
|
||||
|
||||
inline VMReg RegisterImpl::as_VMReg() const {
|
||||
if( this==noreg ) return VMRegImpl::Bad();
|
||||
return VMRegImpl::as_VMReg(encoding() * RegisterImpl::max_slots_per_register);
|
||||
inline VMReg Register::RegisterImpl::as_VMReg() const {
|
||||
return VMRegImpl::as_VMReg(encoding() * Register::max_slots_per_register);
|
||||
}
|
||||
|
||||
inline VMReg FloatRegisterImpl::as_VMReg() const {
|
||||
return VMRegImpl::as_VMReg((encoding() * FloatRegisterImpl::max_slots_per_register) +
|
||||
inline VMReg FloatRegister::FloatRegisterImpl::as_VMReg() const {
|
||||
return VMRegImpl::as_VMReg((encoding() * FloatRegister::max_slots_per_register) +
|
||||
ConcreteRegisterImpl::max_gpr);
|
||||
}
|
||||
|
||||
inline VMReg PRegisterImpl::as_VMReg() const {
|
||||
return VMRegImpl::as_VMReg(encoding() + ConcreteRegisterImpl::max_fpr);
|
||||
inline VMReg PRegister::PRegisterImpl::as_VMReg() const {
|
||||
return VMRegImpl::as_VMReg((encoding() * PRegister::max_slots_per_register) +
|
||||
ConcreteRegisterImpl::max_fpr);
|
||||
}
|
||||
|
||||
#endif // CPU_AARCH64_VMREG_AARCH64_INLINE_HPP
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user