2013-04-03 4 views
9

Как можно проинструктировать gcc излучать idiv (целочисленное деление, udiv и sdiv) инструкции для arm application processors?GCC излучать ARM IDIV инструкции

До сих пор я могу использовать только -mcpu=cortex-a15 с gcc 4.7.

$cat idiv.c 
int test_idiv(int a, int b) { 
    return a/b; 
} 

На ССЗ 4.7 (в комплекте с Android NDK r8e)

$gcc -O2 -mcpu=cortex-a15 -c idiv.c 
$objdump -S idiv.o 

00000000 <test_idiv>: 
    0: e710f110 sdiv r0, r0, r1 
    4: e12fff1e bx lr 

Даже это один дает idiv.c:1:0: warning: switch -mcpu=cortex-a15 conflicts with -march=armv7-a switch [enabled by default] если добавить -march=armv7-a рядом с -mcpu=cortex-a15 и не выделяет idiv инструкции.

$gcc -O2 -mcpu=cortex-a15 -march=armv7-a -c idiv.c 

idiv.c:1:0: warning: switch -mcpu=cortex-a15 conflicts with -march=armv7-a switch [enabled by default] 

$objdump -S idiv.o 
00000000 <test_idiv>: 
    0: e92d4008 push {r3, lr} 
    4: ebfffffe bl 0 <__aeabi_idiv> 
    8: e8bd8008 pop {r3, pc} 

На НКУ 4.6 (в комплекте с Android NDK R8e) не выделяет idiv инструкции на всех, но признает -mcpu=cortex-a15 также не жалуется на -mcpu=cortex-a15 -march=armv7-a комбинации.

Afaik idiv является необязательным на armv7, поэтому должен быть более чистый способ дать указание gcc испустить их, но как?

+0

Вы уверены, что есть настоящая команда называется 'idiv'? Я могу найти только 'sdiv' (подписанное подразделение) и' udiv' (беззнаковое подразделение) ... – unwind

+0

@unwind Я предполагаю idiv = sdiv | udiv – auselen

+0

Какой именно процессор является вашей целью? AFAIK Cortex-A15 поддерживает sdiv/udiv, но Cortex-A5 этого не делает. Оба совместимы с ARMv7-A. –

ответ

5

Если инструкция не указана в описаниях , то я сомневаюсь, что код gcc испустит код. Note1

Вы всегда можете использовать инлайн-ассемблер, чтобы получить инструкции, если компилятор не поддерживает его. Note2 Поскольку ваш op-code довольно редкий/специфичный для машины, возможно, не так много усилий, чтобы получить его в источнике gcc. В частности, есть arch и tune/cpu флаги. tune/cpu предназначен для более конкретной машины, но арка допускает использование всех машин в этой архитектуре. Это op-code, кажется, нарушает это правило, если я понимаю.

Для gcc 4.6.2, это выглядит как Thumb2 и Cortex-r4 являются сигналы, чтобы использовать эти инструкции и как вы с gcc 4.7.2 отмечалось, Cortex-A15, кажется, быть добавлены используйте эти инструкции. С gcc 4.7.2, thumb2.md файл больше не содержит udiv/sdiv. Однако он может быть включен в другое место; Я не на 100% знаком со всем описанием . Также представляется, что cortex-a7, cortex-a15 и cortex-r5 могут включить эти инструкции в 4.7.2. Note3

Это не отвечает на вопрос напрямую, но это дает некоторую информацию/путь, чтобы получить ответ. Вы можете скомпилировать модуль с -mcpu=cortex-r4, хотя это может вызвать проблемы с компоновщиками.Кроме того, существует int my_idiv(int a, int b) __attribute__ ((__target__ ("arch=cortexe-r4")));, где вы можете указать для каждой функции машинное описание, используемое генератором кода. Я сам не использовал их, но это только возможности попробовать. Как правило, вы не хотите поддерживать неправильную машину, поскольку она может генерировать неоптимальные (и, возможно, незаконные) op-коды. Вам придется экспериментировать и, возможно, затем предоставить ответ реальным.

Note1: Это для запасаgcc 4.6.2 и 4.7.2. Я не знаю, есть ли у вашего компилятора Android исправления.

gcc-4.6.2/gcc/config/arm$ grep [ius]div *.md 
arm.md: "...,sdiv,udiv,other" 
cortex-r4.md:;; We guess that division of A/B using sdiv or udiv, on average, 
cortex-r4.md:;; This gives a latency of nine for udiv and ten for sdiv. 
cortex-r4.md:(define_insn_reservation "cortex_r4_udiv" 9 
cortex-r4.md:  (eq_attr "insn" "udiv")) 
cortex-r4.md:(define_insn_reservation "cortex_r4_sdiv" 10 
cortex-r4.md:  (eq_attr "insn" "sdiv")) 
thumb2.md: "sdiv%?\t%0, %1, %2" 
thumb2.md: (set_attr "insn" "sdiv")] 
thumb2.md:(define_insn "udivsi3" 
thumb2.md:  (udiv:SI (match_operand:SI 1 "s_register_operand" "r") 
thumb2.md: "udiv%?\t%0, %1, %2" 
thumb2.md: (set_attr "insn" "udiv")] 
gcc-4.7.2/gcc/config/arm$ grep -i [ius]div *.md 
arm.md: "...,sdiv,udiv,other" 
arm.md: "TARGET_IDIV" 
arm.md: "sdiv%?\t%0, %1, %2" 
arm.md: (set_attr "insn" "sdiv")] 
arm.md:(define_insn "udivsi3" 
arm.md: (udiv:SI (match_operand:SI 1 "s_register_operand" "r") 
arm.md: "TARGET_IDIV" 
arm.md: "udiv%?\t%0, %1, %2" 
arm.md: (set_attr "insn" "udiv")] 
cortex-a15.md:(define_insn_reservation "cortex_a15_udiv" 9 
cortex-a15.md:  (eq_attr "insn" "udiv")) 
cortex-a15.md:(define_insn_reservation "cortex_a15_sdiv" 10 
cortex-a15.md:  (eq_attr "insn" "sdiv")) 
cortex-r4.md:;; We guess that division of A/B using sdiv or udiv, on average, 
cortex-r4.md:;; This gives a latency of nine for udiv and ten for sdiv. 
cortex-r4.md:(define_insn_reservation "cortex_r4_udiv" 9 
cortex-r4.md:  (eq_attr "insn" "udiv")) 
cortex-r4.md:(define_insn_reservation "cortex_r4_sdiv" 10 
cortex-r4.md:  (eq_attr "insn" "sdiv")) 

Примечание2: Смотрите pre-processor as Assembler если gcc проходит опции для gas, которые мешают использовать udiv/sdiv инструкции. Например, вы можете использовать asm(" .long <opcode>\n");, где код операции - это некоторый токен, вставленный в строковый кодированный макрос. Кроме того, вы можете аннотировать ваш ассемблер, чтобы указать изменения в machine. Таким образом, вы можете временно ложь и говорят, у вас есть Cortex-r4 и т.д.

Note3:

gcc-4.7.2/gcc/config/arm$ grep -E 'TARGET_IDIV|arm_arch_arm_hwdiv|FL_ARM_DIV' * 
arm.c:#define FL_ARM_DIV (1 << 23)   /* Hardware divide (ARM mode). */ 
arm.c:int arm_arch_arm_hwdiv; 
arm.c: arm_arch_arm_hwdiv = (insn_flags & FL_ARM_DIV) != 0; 
arm-cores.def:ARM_CORE("cortex-a7", cortexa7, 7A, ... FL_ARM_DIV 
arm-cores.def:ARM_CORE("cortex-a15", cortexa15, 7A, ... FL_ARM_DIV 
arm-cores.def:ARM_CORE("cortex-r5", cortexr5, 7R, ... FL_ARM_DIV 
arm.h: if (TARGET_IDIV)        \ 
arm.h:#define TARGET_IDIV    ((TARGET_ARM && arm_arch_arm_hwdiv) \ 
arm.h:extern int arm_arch_arm_hwdiv; 
arm.md: "TARGET_IDIV" 
arm.md: "TARGET_IDIV" 
+0

(+1) Спасибо за то, что вы отважились на определения машин, я думаю, что могу определить новый тип машины, например * armv7-ad *, копирование из armv7-a. Я не думаю, что вы можете использовать встроенный ассемблер, компилятор все равно будет кричать о несовпадении инструкции. О mach, mcpu, mtune ... Итак, целочисленный div необязателен, он необязателен для mach ... тогда я ожидал бы либо изменения mach, либо дополнительного флага, например fpu. Я ожидаю, что mcpu/mtune даст оптимизатору некоторую информацию о планировании инструкций - вот почему я не решаюсь использовать cortex-a15. – auselen

+0

@auselen Вы попробовали '-mcpu = cortex-a7'? Или это не для вашей машины? Похоже, он дает те же * FL_ARM_DIV * разрешения, что и '-mcpu = cortex-a15'. –

+1

Нет. Предположим, я использую cortex-a9 с поддержкой idiv. Может быть, я могу использовать «-mcpu = cortex-a15 -mtune = cortex-a9», я проверю это позже. – auselen

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