Что такое байтовые регистры в контексте x86 P6? - PullRequest
0 голосов
/ 30 октября 2018

Я пытаюсь кросс-компилировать 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 проверяет некоторые типы регистров, чтобы определить семейство процессоров .

Он определяет процессоры , как указано в комментариях :

//       6   -  PentiumPro, Pentium II, Celeron, Xeon, Pentium III, Athlon,
//              Pentium M, Core Solo, Core Duo, Core2 Duo

У меня ядро ​​скомпилировано для "Pentium Pro", поэтому это должно произойти, однако :

static int  cpu_family()        { return _cpu;}
static bool is_P6()             { return cpu_family() >= 6; }

_cpu назначается 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, которая, как определено функция extended_cpu_family() означает, что он возвращается к классу 4.

Часть 2 - has_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 определяется как :

typedef int                     intptr_t;

Итак, в общем, похоже, что has_byte_registers() терпит неудачу. Я не вижу, как это могло бы когда-либо быть успешным, так как это выглядит так, как будто это должно преобразовываться в область памяти, которая всегда будет выше 16.

Кажется странным, что ожидаемое число регистров байтов не 64-битного процессора в 1061 * 4 раза больше, чем у 64-битного процессора.

Неправильно ли я сконфигурировал свое ядро, является ли один из этих тестов неправильным (чтобы я мог отправить патч) или просто OpenJDK не рассматривал старые "не совсем совместимые" процессоры, подобные этому один

1 Ответ

0 голосов
/ 30 октября 2018

Кажется странным, что ожидаемое число регистров байтов не 64-битного процессора в 4 раза больше, чем у 64-битного процессора.

Да, но таким образом это действительно происходит.

Без префикса 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 соответствует тому, что просто никогда не используется регистр старших байтов.

Я не уверен, что с остальными.

...