Reputation: 929
I'm attempting to cross-compile OpenJDK to an old 32-bit VIA Geode LX processor and I keep hitting this assert:
assert(VM_Version::is_P6() || dest_reg->has_byte_register(),
"must use byte registers if not P6");
Clearly I'm failing both tests, but if I override the warning with -XX:c1_LIRAssembler.cpp:1313
the application runs perfectly fine, so I'm presuming I've misconfigured my kernel somehow, but I don't know what about it I got wrong. One of these has to be true for the assert to pass.
Part 1 - VM_Version::is_P6()
The VIA Geode LX is supposed to be a 686 processor (minus one instruction), but that shouldn't affect the decision being made here which is around the number of registers it can access, not the instruction set. OpenJDK does test for certain types of registers, though, to determine the Processor Family.
It defines CPUs as listed in the comments:
// 6 - PentiumPro, Pentium II, Celeron, Xeon, Pentium III, Athlon,
// Pentium M, Core Solo, Core Duo, Core2 Duo
I have my kernel compiled for "Pentium Pro", so this should succeed, however:
static int cpu_family() { return _cpu;}
static bool is_P6() { return cpu_family() >= 6; }
_cpu
is assigned by extended_cpu_family()
:
static uint32_t extended_cpu_family() {
uint32_t result = _cpuid_info.std_cpuid1_eax.bits.family;
result += _cpuid_info.std_cpuid1_eax.bits.ext_family;
return result;
}
And down the rabbit hole we go.... Suffice to say I can see why this part of the assert would fail. The VIA Geode LX mimics the instruction set of an Intel x86, but fails in a number of cases, so I understand why it wouldn't technically meet the qualification of a P6 which, as defined by the function extended_cpu_family()
means it falls back to a class 4.
Part 2 - has_byte_register()
This is the code that checks for a byte register:
public:
enum {
#ifndef AMD64
number_of_registers = 8,
number_of_byte_registers = 4,
max_slots_per_register = 1
#else
number_of_registers = 16,
number_of_byte_registers = 16,
max_slots_per_register = 1
#endif // AMD64
};
...
bool has_byte_register() const
{ return 0 <= (intptr_t)this && (intptr_t)this < number_of_byte_registers; }
...
where intptr_t
is defined as:
typedef int intptr_t;
So basically what it looks like is that has_byte_registers()
is failing. I don't see how it could ever success, though, since it looks like "this" must resolve to a memory location, which will always be higher than 16.
It does seem odd that the expected number of byte registers of a non-64-bit processor is 4 times that of a 64-bit processor, though.
Did I configure my kernel wrong, is one of these tests wrong (so that I can submit a patch), or is it just that OpenJDK didn't consider old "not-quite-compliant" CPUs like this one?
Upvotes: 2
Views: 172
Reputation: 64913
It does seem odd that the expected number of byte registers of a non-64-bit processor is 4 times that of a 64-bit processor, though.
Yes, but in a way that really happens.
Without a REX prefix there are 8 byte registers, split in two groups:
AL
, DL
, CL
, BL
(the low byte of AX
etc)AH
, DH
, CH
, BH
(the high byte of AX
etc)The high byte registers generally have stranger properties than the low byte registers, and tracking the allocation of different parts of the same register is an annoying extra complication. To simplify the mess it may be a reasonably choice to just not ever use them, but that does mean that the byte register count is down to 4.
With a REX prefix (in 64bit mode, otherwise there is no REX), the lowest byte of all of the 16 GPRs can be used as a byte register.
The high byte registers also still exist in 64bit mode (so in a sense there are 16+4 byte registers in 64bit mode), but cannot be accessed by an instruction that has a REX prefix (even with none of the REX flags set). The high byte registers are extra painful to use in 64bit since, for example add ah, sil
is impossible since sil
requires a REX prefix while ah
requires the lack of a REX prefix. Setting the count to 16 is consistent with simply never using a high byte register.
I'm not sure what's up with the rest though.
Upvotes: 3