【问题标题】:What are byte registers in an x86 P6 context?x86 P6 上下文中的字节寄存器是什么?
【发布时间】: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


    【解决方案1】:

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

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

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

    • 低字节寄存器:ALDLCLBLAX等的低字节)
    • 高字节寄存器:AHDHCHBHAX的高字节等)

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

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

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

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

    【讨论】:

    • 我开始认为他们的意思是移位(intptr_t)this &lt;&lt; number_of_byte_registers,它将确定是否有足够的位可用于分配的架构。
    • @tudor 我认为这不会做有意义的事情
    猜你喜欢
    • 2013-11-22
    • 2013-04-21
    • 1970-01-01
    • 2016-06-01
    • 1970-01-01
    • 2010-10-27
    • 2020-12-24
    • 2012-02-17
    相关资源
    最近更新 更多