2015-12-01 4 views
0

Мы взяли отчет об ошибке для некоторого кода X32 под Кланом на OS X (ошибка показана ниже). Пользователь попытался скомпилировать код в системе Intel x86_64, используя -arch i386. X32 is 32-bit integers, longs and pointers.Является ли __ILP32__ и __i386__ действительной конфигурацией?

Согласно System V Application Binary Interface, AMD64 (With LP64 and ILP32 Programming Models) (стр 104), допустимые конфигурации в одиночку либо __ILP32__ или __ILP32__ и __x86_64__ (и друзей, как amd64 вместо __x86_64__).

Я также проверил SYSTEM V APPLICATION BINARY INTERFACE for Intel386, и он не упоминает __ILP32__ и друзей. Поэтому я не считаю, что __ILP32__ должен присутствовать на чисто 32-битных системах.

Я думаю, что вышеуказанного должно быть достаточно, чтобы ответить на вопрос, но я использую Clang в системе OS X. OS X ABI Function Call Guide doe не обсуждает это, и часто обращается к руководству System V. Тем не менее, ссылка на Руководство по Системе V от 2003 года, которая предшествует X32, поэтому нет никакой обработки.

Мой вопрос, является __ILP32__ и __i386__ действительной комбинации или конфигурации?


Для полноты, вот ошибка кода и компилятора. Я не пытаюсь решить эту проблему.

Исходный код

BOOL_X32 определяется при __ILP32__ определяется в окружающей среде.

asm volatile 
(
    // save ebx in case -fPIC is being used 
# if BOOL_X32 || BOOL_X64 
    "pushq %%rbx; cpuid; mov %%ebx, %%edi; popq %%rbx" 
# else // BOOL_X86 
    "push %%ebx; cpuid; mov %%ebx, %%edi; pop %%ebx" 
# endif 
    : "=a" (output[0]), "=D" (output[1]), "=c" (output[2]), "=d" (output[3]) 
    : "a" (input), "c" (0) 
); 

Ошибка компилятора

X32 является основном 32-битный. Тем не менее, при взаимодействии со стеком с использованием языка ассемблера нам нужно вывести/поп 64-битные регистры и значения.

$ make cpu.o 
clang++ -DNDEBUG -g2 -O2 -arch i386 -fPIC -pipe -c cpu.cpp 
cpu.cpp:104:4: error: register %rbx is only available in 64-bit mode 
         "pushq %%rbx; cpuid; mov %%ebx, %%edi; popq %%rbx" 
         ^
<inline asm>:1:8: note: instantiated into assembly here 
     pushq %rbx; cpuid; mov %ebx, %edi; popq %rbx 
       ^~~~~ 
cpu.cpp:104:4: error: register %rbx is only available in 64-bit mode 
         "pushq %%rbx; cpuid; mov %%ebx, %%edi; popq %%rbx" 
         ^
<inline asm>:1:42: note: instantiated into assembly here 
     pushq %rbx; cpuid; mov %ebx, %edi; popq %rbx 
               ^~~~ 
2 errors generated. 

Наконец, вот макросы препроцессора Clang, когда с помощью -arch i386 на системе x86_64:

$ clang++ -arch i386 -dM -E - < /dev/null | egrep -i "(86|64|ilp)" 
#define _ILP32 1 
#define __ILP32__ 1 
... 
#define __i386 1 
#define __i386__ 1 
#define i386 1 
+0

Я здесь смущен; давайте сделаем резервную копию в секунду. Архитектура X32 не определена в Mac OS X. Что вы пытаетесь скомпилировать и как? – duskwuff

+0

@duskwuff - если его не определено, то почему Clang определяет '__ILP32__', когда используется' -arch i386'? (Я также попытался улучшить поток вопроса и добавил вывод препроцессора). – jww

ответ

1

Да, __i386__ с __ILP32__ это вполне допустимая конфигурация. Это означает, что вы строите код для 32-разрядного x86 в компиляторе, где int, long и указатели имеют ширину 32 бит.

Хотя имена модели данных, такие как «ILP32», обычно используются для описания 64-разрядных систем, использование такого имени или наличие макроса, связанного с ним, не подразумевает ничего общего с набором команд. Хотя System V ABI не указывает, что этот макрос должен присутствовать в 32-битной системе, он также не утверждает, что он не должен присутствовать!

В любом случае. Если вам нужно определить, какой набор инструкций используется, используйте __i386__ и __x86_64__; для этого они и есть.

+0

Итак, вот что я нашел (как вы указали) .... Да, его действительная конфигурация, и система V ABI не запрещает ее. Фактически, он также используется в некоторых системах ARM. С учетом этого .... GCC, MSVC (Microsoft) и ICC (Intel) не определяют его для 32-битных целей. GCC и ICC определяют его только для X32. Clang определяет его для всех 32-битных целей. У меня нет компилятора Comeau для тестирования. – jww

Смежные вопросы