LLVM MC's integrated assembler supports most LLVM targets, including IA-32, x86-64, ARM, and ARM64. For some targets, including the various MIPS instruction sets, integrated assembly support is usable but still in the beta stage.
The basic option is to define the target architecture. For that, use -target <triple> . If you don't specify the target, CPU names won't match (since Clang assumes the host triple), and the compilation will go ahead, creating code for the host platform, which will break later on when assembling or linking.
Clang-cl support As part of the LLVM 12 release, LLVM supports clang-cl, a compatibility layer for Microsoft Visual C++ (MSVC). This means that most developers can use clang-cl to compile their C/C++ applications on Visual Studio/MSBuild on the Windows on Arm device, without needing to change the command line.
The -cc1 argument indicates that the compiler front-end is to be used, and not the driver. The clang -cc1 functionality implements the core compiler functionality. So, simply speaking. If you do not give -cc1 then you can expect the "look&feel" of standard GCC.
So far as I can tell, there is no command-line option to list which architectures a given clang
binary supports, and even running strings
on it doesn't really help. Clang is essentially just a C to LLVM translator, and it's LLVM itself that deals with the nitty-gritty of generating actual machine code, so it's not entirely surprising that Clang isn't paying much attention to the underlying architecture.
As others have already noted, you can ask llc
which architectures it supports. This isn't all that helpful not just because these LLVM components might not be installed, but because of the vagaries of search paths and packaging systems, your llc
and clang
binaries may not correspond to the same version of LLVM.
However, for the sake of argument, let's say that you compiled both LLVM and Clang yourself or that you're otherwise happy to accept your LLVM binaries as good enough:
llc --version
will give a list of all architectures it supports. By default, it is compiled to support all architectures. What you may think of as a single architecture such as ARM may have several LLVM architectures such as regular ARM, Thumb and AArch64. This is mainly for implementation convenience because the different execution modes have very different instruction encodings and semantics.llc -march=ARCH -mattr=help
will list "available CPUs" and "available features". The CPUs are generally just a convenient way of setting a default collection of features.But now for the bad news. There is no convenient table of triples in Clang or LLVM that can be dumped, because the architecture-specific backends have the option of parsing the triple string into an llvm::Triple
object (defined in include/llvm/ADT/Triple.h). In other words, to dump all available triples requires solving the Halting Problem. See, for example, llvm::ARM_MC::ParseARMTriple(...)
which special-cases parsing the string "generic"
.
Ultimately, though, the "triple" is mostly a backwards-compatibility feature to make Clang a drop-in replacement for GCC, so you generally don't need to pay much attention to it unless you are porting Clang or LLVM to a new platform or architecture. Instead, you will probably find the output of llc -march=arm -mattr=help
and boggling at the huge array of different ARM features to be more useful in your investigations.
Good luck with your research!
I am using Clang 3.3, I think the best way to get the answer is reading the source code. in 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
};
and in clang/lib/Driver/ToolChains.cpp , there is sth about arm.
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);
}
One hint you can do: if you're trying to find a particular target triple, is to install llvm on that system then do a
$ llc --version | grep Default
Default target: x86_64-apple-darwin16.1.0
or alternatively:
$ llvm-config --host-target
x86_64-apple-darwin16.0.0
or
$ clang -v 2>&1 | grep Target
Target: x86_64-apple-darwin16.1.0
Then you know how to target it when cross compiling anyway.
Apparently there are "lots" of targets out there, here's a list, feel free to add to it, community wiki style:
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
Here's what the docs list anyway (apparently it's a quadruple [or quintuple?] instead of a triple these days):
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.
and you can even fine tune specify a target cpu beyond this, though it uses a sensible default for the target cpu based on the triple.
Sometimes targets "resolve" to the same thing, so to see what a target is actually treated as:
$ clang -target x86_64-w64-mingw32 -v 2>&1 | grep Target
Target: x86_64-w64-windows-gnu
According to Jonathan Roelofs in this talk “Which targets does Clang support?”:
$ 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
Future versions of Clang may provide the following. They are listed as "proposed" though not yet available at least as of 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With