Компиляторы
Целевые архитектуры: x86, ARM, RISC-V
iOS приложение на iPhone с ARM64, Android на x86 в эмуляторе, Node.js сервер на Linux x86-64 - один и тот же TypeScript исходник. Кросс-компиляция и знание целевой архитектуры позволяют одному компилятору генерировать нативный код для десятков платформ. LLVM поддерживает 40+ архитектур из одной кодовой базы.
- **Apple Silicon** (M1/M2/M3) - AArch64 с проприетарными расширениями AMX для matrix операций. Rosetta 2 переводит x86-64 бинарники в AArch64 на лету через JIT-трансляцию - именно понимание ABI двух архитектур делает это возможным.
- **Rust embedded** (bare metal ARM Cortex-M): `thumbv7em-none-eabihf` target - ARM Thumb2 ISA, no OS, hard float ABI. cargo build кросс-компилирует для микроконтроллера прямо с MacBook или Linux x86-64 - без нужды в отдельной ARM машине.
- **WebAssembly** - 4-я доминирующая ISA в web: WASM bytecode запускается в браузерах, Node.js, Wasmtime. Clang и Rust компилируют в WASM так же как в x86 - просто другой target triple (`wasm32-unknown-unknown`).
ISA: x86 vs ARM vs RISC-V
ISA (Instruction Set Architecture) - интерфейс между программным обеспечением и железом: набор инструкций, форматы операндов, регистры, модели памяти. Три доминирующих ISA в современных системах - x86-64 (CISC), ARM64/AArch64 (RISC), RISC-V (open RISC).
RISC-V стал стандартом де-факто для embedded и open-source процессоров. SiFive, RISC-V International, Western Digital, Google и Samsung разрабатывают RISC-V чипы. ESP32-C3 (популярный IoT чип) - RISC-V. Apple M-серия - AArch64 с проприетарными расширениями (AMX для matrix operations). Qualcomm Snapdragon - AArch64 с расширениями Hexagon DSP.
Почему RISC архитектуры (ARM, RISC-V) имеют только load/store инструкции для работы с памятью?
Calling Conventions
Calling convention - соглашение о том, как функции передают аргументы и возвращают значения: какие регистры используются, кто сохраняет регистры (caller или callee), как выравнивается стек. Нарушение calling convention = undefined behaviour или crash.
Calling conventions критичны для FFI (Foreign Function Interface) - вызов C из Rust/Python/Go. Rustc генерирует `extern "C"` функции в точном соответствии с System V AMD64 ABI. Нарушение хотя бы одного регистра = мусор в аргументах или caller'овские данные перезаписаны. Clang с `-cc1 -calling-conv` позволяет экспериментировать с нестандартными calling conventions.
Чем отличаются caller-saved и callee-saved регистры?
ABI Stability
ABI (Application Binary Interface) - более широкое понятие чем calling convention: включает layout структур данных в памяти, name mangling, vtable layout, exception handling механизмы. ABI стабильность критична для shared libraries: `.so`/`.dll` скомпилированные пять лет назад должны работать с новой программой.
C++ имеет Itanium ABI как де-факто стандарт на Linux (GCC, Clang, Intel ICC совместимы). Windows MSVC использует другой ABI - именно поэтому `.lib` скомпилированные MSVC не работают с mingw/clang без специальных шагов. Swift имеет стабильный ABI начиная с Swift 5.0 (2019) - до этого приходилось перекомпилировать все зависимости при обновлении Swift. Rust намеренно не фиксирует ABI для нативного Rust-to-Rust - это позволяет оптимизировать передачу аргументов.
Почему C++ библиотека скомпилированная MSVC несовместима с GCC на Windows?
Cross-Compilation
Cross-compilation - компиляция для архитектуры, отличной от той на которой запускается компилятор. MacBook M1 компилирует код для x86-64 Linux или ARM64 Android. Требует: cross toolchain (компилятор + linker + sysroot с целевыми заголовками и библиотеками).
LLVM изначально проектировался как cross-compilation friendly: один компилятор, все цели. Clang с нужным target triple компилирует для любой из ~40 поддерживаемых архитектур. Rustup target add добавляет precompiled стандартную библиотеку для целевой архитектуры. Sysroot - каталог с заголовочными файлами и библиотеками целевой платформы, без него cross-compilation невозможна для C/C++.
Что такое sysroot при cross-compilation?
Итоги
- **ISA** определяет набор инструкций и регистров. RISC (ARM, RISC-V) - простой конвейер, load/store архитектура. CISC (x86) - сложный декодер, reg-mem инструкции.
- **Calling conventions** - соглашение о регистрах для аргументов и возврата. SysV AMD64: rdi, rsi, rdx... Windows x64: rcx, rdx, r8, r9. Несовместимы!
- **ABI** включает struct layout, name mangling, vtable. C++ MSVC vs GCC ABI несовместимы. Rust не фиксирует native ABI намеренно.
- **Cross-compilation** требует target triple + sysroot. LLVM/Clang поддерживают 40+ архитектур. Rust: `rustup target add` + `cargo build --target`.
Связанные темы
Целевая архитектура определяет все решения backend компилятора:
- Выбор инструкций — Паттерны instruction selection полностью зависят от ISA целевой архитектуры
- Линковка и загрузка — ABI и формат объектных файлов (ELF, Mach-O, PE) связывают архитектуру и линковку
- Планирование инструкций — Латентности и pipeline модели специфичны для каждой архитектуры
Вопросы для размышления
- RISC-V открытый стандарт без роялти - почему крупные компании не переходят на него массово и продолжают использовать ARM? Какие технические и нетехнические барьеры существуют?
- Rust намеренно не фиксирует native ABI чтобы иметь свободу оптимизации. Какие конкретные оптимизации это позволяет - например, как можно оптимизировать передачу `Option<NonNull<T>>`?
- WebAssembly имеет собственный ABI. При компиляции C++ в WASM name mangling сохраняется или нет? Как работает FFI между WASM модулями на разных языках?