trabajo - clang: ¿cómo enumerar las arquitecturas de destino compatibles?
como poner numero de pagina en word despues del indice (6)
Actualmente estoy interesado en ARM en general y específicamente en los objetivos de iPhone / Android. Pero solo quiero saber más sobre clang, ya que parece desempeñar un papel importante en los años venideros.
Lo intenté
clang -cc1 --help|grep -i list
clang -cc1 --help|grep arch|grep -v search
clang -cc1 --help|grep target
-triple <value> Specify target triple (e.g. i686-apple-darwin9)
Sé que clang tiene el parámetro -triplet, pero ¿cómo puedo enumerar todos los valores posibles para él? Descubrí que el clang es muy diferente de gcc con respecto a la compilación cruzada, en el mundo GCC debes tener un binario separado para todo, como PLATFORM_make o PLATFORM_ld (i * 86-pc-cygwin i * 86 - * - linux-gnu etc. http://git.savannah.gnu.org/cgit/libtool.git/tree/doc/PLATFORMS )
en clang world, es solo un binario (como leo en algunos foros). ¿Pero cómo obtengo la lista de objetivos compatibles? Y si mi objetivo no es compatible con mi distribución (linux / windows / macos / whatever) ¿cómo puedo obtener la que admite más plataforma?
si hago un SVN más reciente como este:
svn co http://llvm.org/svn/llvm-project/cfe/trunk clang
¿obtendré la mayoría de las plataformas? Parece que Clang no se construyó con la compilación cruzada en mente de inmediato, pero dado que se basa en la realidad, debería ser muy amigable para todos en teoría. ¡gracias!
Estoy usando Clang 3.3, creo que la mejor manera de obtener la respuesta es leyendo el código fuente. en llvm / ADT / Triple.h ( http://llvm.org/doxygen/Triple_8h_source.html ):
enum ArchType {
UnknownArch,
arm, // ARM: arm, armv.*, xscale
aarch64, // AArch64: aarch64
hexagon, // Hexagon: hexagon
mips, // MIPS: mips, mipsallegrex
mipsel, // MIPSEL: mipsel, mipsallegrexel
mips64, // MIPS64: mips64
mips64el,// MIPS64EL: mips64el
msp430, // MSP430: msp430
ppc, // PPC: powerpc
ppc64, // PPC64: powerpc64, ppu
r600, // R600: AMD GPUs HD2XXX - HD6XXX
sparc, // Sparc: sparc
sparcv9, // Sparcv9: Sparcv9
systemz, // SystemZ: s390x
tce, // TCE (http://tce.cs.tut.fi/): tce
thumb, // Thumb: thumb, thumbv.*
x86, // X86: i[3-9]86
x86_64, // X86-64: amd64, x86_64
xcore, // XCore: xcore
mblaze, // MBlaze: mblaze
nvptx, // NVPTX: 32-bit
nvptx64, // NVPTX: 64-bit
le32, // le32: generic little-endian 32-bit CPU (PNaCl / Emscripten)
amdil, // amdil: amd IL
spir, // SPIR: standard portable IR for OpenCL 32-bit version
spir64 // SPIR: standard portable IR for OpenCL 64-bit version
};
y en clang / lib / Driver / ToolChains.cpp, hay algo sobre el brazo.
static const char *GetArmArchForMArch(StringRef Value) {
return llvm::StringSwitch<const char*>(Value)
.Case("armv6k", "armv6")
.Case("armv6m", "armv6m")
.Case("armv5tej", "armv5")
.Case("xscale", "xscale")
.Case("armv4t", "armv4t")
.Case("armv7", "armv7")
.Cases("armv7a", "armv7-a", "armv7")
.Cases("armv7r", "armv7-r", "armv7")
.Cases("armv7em", "armv7e-m", "armv7em")
.Cases("armv7f", "armv7-f", "armv7f")
.Cases("armv7k", "armv7-k", "armv7k")
.Cases("armv7m", "armv7-m", "armv7m")
.Cases("armv7s", "armv7-s", "armv7s")
.Default(0);
}
static const char *GetArmArchForMCpu(StringRef Value) {
return llvm::StringSwitch<const char *>(Value)
.Cases("arm9e", "arm946e-s", "arm966e-s", "arm968e-s", "arm926ej-s","armv5")
.Cases("arm10e", "arm10tdmi", "armv5")
.Cases("arm1020t", "arm1020e", "arm1022e", "arm1026ej-s", "armv5")
.Case("xscale", "xscale")
.Cases("arm1136j-s", "arm1136jf-s", "arm1176jz-s", "arm1176jzf-s", "armv6")
.Case("cortex-m0", "armv6m")
.Cases("cortex-a8", "cortex-r4", "cortex-a9", "cortex-a15", "armv7")
.Case("cortex-a9-mp", "armv7f")
.Case("cortex-m3", "armv7m")
.Case("cortex-m4", "armv7em")
.Case("swift", "armv7s")
.Default(0);
}
Hasta donde puedo decir, no hay una opción de línea de comandos para enumerar qué arquitecturas admite un binario clang
dado, e incluso ejecutar strings
en él no ayuda realmente. Clang es esencialmente solo un traductor de C a LLVM, y es el propio LLVM el que trata con los detalles de la generación de código de máquina real, por lo que no es del todo sorprendente que Clang no esté prestando mucha atención a la arquitectura subyacente.
Como ya han notado otros, puede preguntarle a llc
qué arquitecturas admite. Esto no es del todo útil, no solo porque estos componentes de LLVM pueden no estar instalados, sino por los caprichos de las rutas de búsqueda y los sistemas de empaque, sus binarios de llc
y clang
pueden no corresponder a la misma versión de LLVM.
Sin embargo, en aras de la argumentación, digamos que compiló LLVM y Clang usted mismo o que está de acuerdo en aceptar sus archivos binarios de LLVM como suficientemente buenos:
-
llc --version
dará una lista de todas las arquitecturas que admite. Por defecto, está compilado para admitir todas las arquitecturas. Lo que puede pensar como una arquitectura única como ARM puede tener varias arquitecturas LLVM como ARM regular, Thumb y AArch64. Esto es principalmente para conveniencia de implementación porque los diferentes modos de ejecución tienen codificaciones y semántica de instrucciones muy diferentes. - Para cada una de las arquitecturas enumeradas,
llc -march=ARCH -mattr=help
mostrará una lista de las "CPU disponibles" y las "funciones disponibles". Por lo general, las CPU son solo una forma conveniente de establecer una colección predeterminada de características.
Pero ahora por las malas noticias. No existe una tabla conveniente de tripletas en Clang o LLVM que se pueda volcar, porque los servidores específicos de la arquitectura tienen la opción de analizar la cadena triple en un objeto llvm::Triple
(definido en include/llvm/ADT/Triple.h ) . En otras palabras, para volcar todas las tripletas disponibles es necesario resolver el problema de detención. Consulte, por ejemplo, llvm::ARM_MC::ParseARMTriple(...)
qué casos especiales analizan la cadena "generic"
.
En última instancia, sin embargo, el "triple" es principalmente una característica de compatibilidad con versiones anteriores para hacer que Clang sea un reemplazo directo para GCC, por lo que generalmente no es necesario prestarle demasiada atención a menos que transfiera Clang o LLVM a una nueva plataforma o arquitectura En cambio, probablemente encontrará la salida de llc -march=arm -mattr=help
y alucinante en la gran variedad de diferentes características de ARM para ser más útil en sus investigaciones.
¡Buena suerte con tu investigación!
Intenta también
> llc -mattr=help
Available CPUs for this target:
amdfam10 - Select the amdfam10 processor.
athlon - Select the athlon processor.
athlon-4 - Select the athlon-4 processor.
athlon-fx - Select the athlon-fx processor.
athlon-mp - Select the athlon-mp processor.
athlon-tbird - Select the athlon-tbird processor.
athlon-xp - Select the athlon-xp processor.
athlon64 - Select the athlon64 processor.
athlon64-sse3 - Select the athlon64-sse3 processor.
atom - Select the atom processor.
...
Available features for this target:
16bit-mode - 16-bit mode (i8086).
32bit-mode - 32-bit mode (80386).
3dnow - Enable 3DNow! instructions.
3dnowa - Enable 3DNow! Athlon instructions.
64bit - Support 64-bit instructions.
64bit-mode - 64-bit mode (x86_64).
adx - Support ADX instructions.
...
No mostrará todas las tripletas, pero
llvm-as < /dev/null | llc -mcpu=help
al menos enumerará todas las CPU.
Según Jonathan Roelofs en esta charla llvm.org/devmtg/2014-04/PDFs/LightningTalks/… :
$ llc --version
LLVM (http://llvm.org/):
LLVM version 3.6.0
Optimized build with assertions.
Built Apr 2 2015 (01:25:22).
Default target: x86_64-apple-darwin12.6.0
Host CPU: corei7-avx
Registered Targets:
aarch64 - AArch64 (little endian)
aarch64_be - AArch64 (big endian)
amdgcn - AMD GCN GPUs
arm - ARM
arm64 - ARM64 (little endian)
armeb - ARM (big endian)
cpp - C++ backend
hexagon - Hexagon
mips - Mips
mips64 - Mips64 [experimental]
mips64el - Mips64el [experimental]
mipsel - Mipsel
msp430 - MSP430 [experimental]
nvptx - NVIDIA PTX 32-bit
nvptx64 - NVIDIA PTX 64-bit
ppc32 - PowerPC 32
ppc64 - PowerPC 64
ppc64le - PowerPC 64 LE
r600 - AMD GPUs HD2XXX-HD6XXX
sparc - Sparc
sparcv9 - Sparc V9
systemz - SystemZ
thumb - Thumb
thumbeb - Thumb (big endian)
x86 - 32-bit X86: Pentium-Pro and above
x86-64 - 64-bit X86: EM64T and AMD64
xcore - XCore
Las versiones futuras de Clang pueden proporcionar lo siguiente. Se enumeran como "propuestas", aunque todavía no están disponibles al menos a partir de v 3.9.0:
$ clang -target <target_from_list_above> --print-multi-libs
$ clang -print-supported-archs
$ clang -march x86 -print-supported-systems
$ clang -march x86 -print-available-systems
Una sugerencia que puedes hacer: si estás tratando de encontrar un objetivo objetivo en particular, es instalar llvm en ese sistema y luego hacer una
$ llc --version | grep Default
Default target: x86_64-apple-darwin16.1.0
o alternativamente:
$ llvm-config --host-target
x86_64-apple-darwin16.0.0
or
$ clang -v 2>&1 | grep Target
Target: x86_64-apple-darwin16.1.0
Entonces sabes cómo orientarlo cuando compilas de todos modos.
Aparentemente hay muchos "objetivos", aquí hay una lista, siéntase libre de agregar, estilo wiki de la comunidad:
arm-none-eabi
armv7a-none-eabi
arm-linux-gnueabihf
arm-none-linux-gnueabi
i386-pc-linux-gnu
x86_64-apple-darwin10
i686-w64-windows-gnu # same as i686-w64-mingw32
x86_64-pc-linux-gnu # from ubuntu 64 bit
x86_64-unknown-windows-cygnus # cygwin 64-bit
x86_64-w64-windows-gnu # same as x86_64-w64-mingw32
i686-pc-windows-gnu # MSVC
x86_64-pc-windows-gnu # MSVC 64-BIT
Esto es lo que la lista de docs todos modos (aparentemente es un cuádruple [¿o quíntuple?] En lugar de un triple en estos días):
The triple has the general format <arch><sub>-<vendor>-<sys>-<abi>, where:
arch = x86, arm, thumb, mips, etc.
sub = for ex. on ARM: v5, v6m, v7a, v7m, etc.
vendor = pc, apple, nvidia, ibm, etc.
sys = none, linux, win32, darwin, cuda, etc.
abi = eabi, gnu, android, macho, elf, etc.
e incluso puede ajustar con precisión una CPU objetivo más allá de esto, aunque usa un valor predeterminado sensato para la CPU objetivo basada en el triple.
A veces los objetivos "resuelven" lo mismo, para ver en qué se trata realmente un objetivo como:
$ clang -target x86_64-w64-mingw32 -v 2>&1 | grep Target
Target: x86_64-w64-windows-gnu