Архитектура ARM

  • ARM: Advanced RISC Machine
    • Область применения: встраиваемые системы
    • Разработчик: компания ARM Holdings, лицензирует дизайн процессора производителям оборудования
  • Основные особенности:
    • Энергоэффективность
    • Низкая стоимость
    • Относительно простое ядро
    • Расширяемость
Архитектура Семейство процессоров Год Примеры устройств
ARMv1 ARM1 1985
ARMv2 ARM2, ARM3
ARMv3 ARM6, ARM7 1992
ARMv4 StrongARM, ARM7TDMI, ARM9TDMI 2003 iPaq 4150
ARMv5 ARM7EJ, ARM9E, ARM10E, XScale
ARMv6 ARM11 2007 iPhone (orig, 3G)
ARMv7 Cortex A8, Cortex A9 2008 N900, iPhone (3GS, 4, 4S)
ARMv8 Cortex-A53, Cortex-A57, Cortex-A72 2011

RISC vs CISC

  • Reduced vs Complex Instruction Set Computer
  • Простые операции
    • Ограниченный набор простых команд (например, нет деления)
    • Команда выполняется за один такт
    • Фиксированная длина команды (простота декодирования)
  • Конвейер
    • Каждая операция разбивается на однотипные простые этапы, которые выполняются параллельно
    • Каждый этап занимает 1 такт, в т.ч. декодирование
  • Регистры
    • Много однотипных взаимозаменяемых регистров (могут использоваться и для данных, и для адресации)

RISC vs CISC

  • Модель работы с памятью
    • Отдельные команды для загрузки/сохранения в память
    • Команды обработки данных работают только с регистрами
  • Сложность оптимизаций перенесена из процессора в компилятор
    • Производительность сильно зависит от компилятора
  • Итого: более простое ядро, выше частота процессора

Режимы процессора ARM

  • ARM (32 бит)
    • Режим по умолчанию
    • Доступны все команды процессора, работа с сопроцессором
  • Thumb - 1 (16 бит )
    • Высокая плотность кода, лучшее использование I-Cache
    • На 16-битной памяти команда передается за один такт
    • Ограниченный набор команд и регистров

Режимы процессора ARM

  • Thumb-2 (смешанный 16/32 бит)
    • Объединяет преимущества ARM и Thumb-1
    • Размер кода на 25% меньше при сравнимой производительности
  • Jazelle (8 бит)
    • Аппаратно реализовано свыше 60% команд Java-байткода
    • Режим доступен только производителям оборудования

Регистры

  • 16 регистров общего назначения
  • Размер: 32 бита, используются в целочисленных командах, полностью взаимозаменяемые
  • Именование: r0 - r15
  • Некоторые регистры имеют специальные имена и назначение:
  • PC (r15) – Program Counter
  • LR (r14) – Link Register
  • SP (r13) – Stack Pointer

Регистры

  • Регистры состояния
  • CPSR (Current Program Status Register): флаги, обработка прерываний
  • SPSR (Saved Program Status Register): хранит копию CPSR при обработке прерывания
  • Доступ: команды MRS/MSR
  • Контрольные регистры
  • Изменения параметров кэширования, управления памятью, режимов процессора и т.п.
  • Доступ: команды MRC/MCR
  • Вещественные регистры (FPU и векторного сопроцессора)

Условные флаги

Флаги расположены в регистре CPSR (current program status register)

Установка флагов

  • Если команда ALU имеет суффикс ’S’, то флаги будут установлены в соответствии с результатом команды.
subs r1, r2, #1
lsls r1, r2, #5
cmp r2, #1				    
				    

Коды условий

Условное выполнение

Почти все команды ARM могут быть записаны в условной форме. В этом случае условие приписывается после команды, и она будет выполнена, только если условие истинно.

addge r1, r1, r1				    


// вычисление модуля |r1 – r2|:
subs r1, r1, r2
rsblt r1, r1, #0
				    

Модуль сдвига

  • Второй аргумент ALU-команд может быть представлен в виде
ARG2 = R shift_op B, где 				    
				    
  • R – регистр
  • B – величина сдвига (0-31)
  • shift_op – один из LSL, ASL, RSL, ROR или RRX
add r1, r1, r1 lsl #2 // r1 = r1 + r1 *4 = r1 * 5				    
				    

Представление констант

Второй аргумент ALU-команд может быть также константой, которая кодируется 12 битами (8 бит значение, 4 бита величина сдвига):

CONST_32 = CONST_8 << (2 * N), 0 <= N < 16
				    
  • and r1, r1, #255
  • and r1, r1, #510 // 510 = 255 << 1 – нечетный сдвиг
  • and r1, r1, #0xff00ff00 // значение «шире» 8 бит
  • and r1, r1, #0xff000000

Режимы процессора ARM

Команды работы с памятью

Команды загрузки/сохранения LDR / STR:

ldr r1, [r2, #+/-imm12]
ldr r1, [r2, r1, [r2, +/-r3, shift imm5]

// Примеры
ldr r1, [pc, #256]
ldr r1, [sp, r2, asl #2]
L1:
ldr r1, L1 + 248
ldr pc, [r1, r2, asl #2] // table-jump для switch
				    

Команды работы со стеком
  • Работа со стеком реализуется через команды stmdb/ldmia
push {r0 push {r0-r15} pop {r0 pop {r0-r15}
stmdb sp!, {r0, r15} ldmia sp!, {r0, r15}				    
				    

Вызов функций

  • Вызов функций выполняется при помощи команды bl – branch with link
  • Текущее значение регистра pc сохраняется в регистре lr
  • Возврат из функции выполняется с помощью команды bx lr
some_func:
    push {lr}
    …
    pop {pc} bx lr				    

bl some_func
some_func:
    bx lr
				    

Конвейер современного ARM

  • Cortex-A8
  • Конвейер из 13 стадий
  • 2 АЛУ устройства, 1 Load/Store, 1 Multiply
  • Может выполнять до 2-х команд за такт
  • Из них должно быть не более одной Load/Store и Multiply, причем умножение должно идти первым
  • Cortex-A9: добавлено динамическое переупорядочение команд

Примеры описания времени выполнения команд на конвейере

  • Этапы конвейера обознаются E1, E2, …, E5
  • Перед началом каждого этапа команда может требовать готовности операндов в регистрах, а после – выдавать готовые операнды
  • ADD r1, r2, r3
  • r2, r3: требуются перед E2
  • r1: после E2

Примеры описания времени выполнения команд на конвейере

  • MOV r1, r2 asl #const
  • r2: требуется перед E1
  • r1: готов после E1
  • Следствие 1: mov r2, r1; add r3, r2, r1 могут начать выполняться одновременно
  • Следствие 2: add r1, r2, r3; mov r2, r1 (в обратном порядке) имеют задержку в 2 такта между командами

Селективный планировщик

Улучшения кодогенерации для ARM Advanced SIMD (NEON)

Улучшение оптимизации GCSE и комбинирования команд в GCC