java - x86 P6 上下文中的字节寄存器是什么?

标签 java x86 cross-compiling cpu-registers 32-bit

我正在尝试将 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; }

_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;
}

然后我们就进入了兔子洞......足以说我可以理解为什么断言的这一部分会失败。 VIA Geode LX 模仿 Intel x86 的指令集,但在很多情况下都会失败,所以我理解为什么它在技术上不符合 P6 的资格,如 function extended_cpu_family() 所定义的意味着它回落到 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_t is defined as:

typedef int                     intptr_t;

所以基本上看起来是 has_byte_registers() 失败了。不过,我不知道它如何能够成功,因为看起来“this”必须解析为一个内存位置,该位置始终高于 16。

不过,非 64 位处理器的预期字节寄存器数量是 64 位处理器的4 倍,这似乎很奇怪。

我的内核配置是否错误,这些测试之一是否错误(以便我可以提交补丁),或者只是 OpenJDK 没有考虑像这样的旧的“不完全兼容”CPU一个?

最佳答案

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.

是的,但在某种程度上确实发生了。

没有 REX 前缀,有 8 个字节寄存器,分为两组:

  • 低字节寄存器:AL , DL , CL , BL (AX等的低字节)
  • 高字节寄存器:AH , DH , CH , BH (AX等的高字节)

高字节寄存器通常比低字节寄存器具有更奇怪的属性,并且跟踪同一寄存器的不同部分的分配是一个烦人的额外复杂性。为了简化困惑,不使用它们可能是一个合理的选择,但这确实意味着字节寄存器计数降至 4。

带有REX前缀(64位模式下,否则没有REX),所有16个GPR的最低字节都可以用作字节寄存器。

高字节寄存器在 64 位模式下仍然存在(因此在某种意义上,64 位模式下有 16+4 字节寄存器),但不能由具有 REX 前缀的指令访问(即使没有任何 REX 标志)放)。高字节寄存器在 64 位中使用起来非常痛苦,例如 add ah, sil不可能,因为 sil需要 REX 前缀,而 ah要求缺少 REX 前缀。将计数设置为 16 与从不使用高字节寄存器是一致的。

不过我不确定其余的情况如何。

关于java - x86 P6 上下文中的字节寄存器是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53055682/

相关文章:

cross-compiling - 防止 SCons 寻找标准工具

java - 如何将目录添加到特定 Tomcat 7 上下文的类路径?

java - 我是否必须捕获尝试将值解析为 int 或 long 的 NumberFormatException?

debugging - QEMU gdb 不显示固件说明

c 库 x86/x64 汇编程序

c++ - 使用依赖项 : how to get target dependencies on host? 交叉编译

java - 如何使用html、servlet将图像插入mysql

java - Spring 和接口(interface)

assembly - intel机器码转汇编代码的问题

linux - 交叉编译编译器何时有意义?