【发布时间】:2019-04-02 23:39:46
【问题描述】:
我正在尝试将 OpenJDK 交叉编译到旧的 32 位 VIA Geode LX 处理器,但我一直在点击 this assert:
assert(VM_Version::is_P6() || dest_reg->has_byte_register(),
"must use byte registers if not P6");
显然我没有通过这两个测试,但是如果我用-XX:c1_LIRAssembler.cpp:1313 覆盖警告,应用程序运行得非常好,所以我假设我以某种方式错误配置了我的内核,但我不知道该怎么办错了。其中一项必须为真,断言才能通过。
第 1 部分 - VM_Version::is_P6()
VIA Geode LX 应该是一个 686 处理器(减去一条指令),但这不应该影响这里所做的决定,即它可以访问的寄存器数量,而不是指令集。不过,OpenJDK 确实会测试某些类型的寄存器以确定 处理器系列。
它定义了 CPU as listed in the comments:
// 6 - PentiumPro, Pentium II, Celeron, Xeon, Pentium III, Athlon,
// Pentium M, Core Solo, Core Duo, Core2 Duo
我已经为“Pentium Pro”编译了内核,所以这应该会成功,however:
static int cpu_family() { return _cpu;}
static bool is_P6() { return cpu_family() >= 6; }
_cpuis assigned byextended_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;
}
然后我们去了兔子洞......我可以说我明白为什么这部分断言会失败。威盛 Geode LX 模仿了 Intel x86 的指令集,但在许多情况下都失败了,所以我理解为什么它在技术上不符合 @ 定义的 P6 的资格。 987654326@ 表示它回退到第 4 类。
第 2 部分 - has_byte_register()
这是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; }
...
在哪里intptr_tis defined as:
typedef int intptr_t;
所以基本上看起来has_byte_registers() 失败了。不过,我看不出它是如何成功的,因为看起来“this”必须解析为一个内存位置,该位置总是高于 16。
不过,非 64 位处理器的预期字节寄存器数量是 64 位处理器的 4 倍,这似乎很奇怪。
我是否配置了我的内核错误,这些测试之一是否错误(以便我可以提交补丁),或者仅仅是 OpenJDK 没有考虑像这样的旧“不完全兼容”CPU一个?
【问题讨论】:
标签: java cross-compiling 32-bit cpu-registers