Discussion:
-mfpu=neon-fp-armv8 and unrecognized command line option
Jeffrey Walton
2016-07-20 21:14:10 UTC
Permalink
Hi Everyone,

I'm having trouble with ARMv8/Aarch64. One is an early Mustang server
board (without CRC or Crypto), and the other is a LeMaker HiKey (with
CRC and Crypto). Both run Linaro:

apm-mustang: $ cat /proc/cpuinfo
Features : fp asimd evtstrm

And:

hikey: $ cat /proc/cpuinfo
Features : fp asimd evtstrm aes pmull sha1 sha2 crc32

According to the GCC folks, we can get better code generation with
-mfpu=neon-fp-armv8
(http://gcc.gnu.org/ml/gcc-help/2016-05/msg00058.html and
https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html). However, it
results in:

$ g++ -DDEBUG -g3 -O0 -mfpu=neon-fp-armv8 -fPIC -pipe -c cryptlib.cpp
g++: error: unrecognized command line option ‘-mfpu=neon-fp-armv8’
GNUmakefile:753: recipe for target 'cryptlib.o' failed

It looks like -mfpu=neon-fp-armv8 is a GCC 4.9 feature
(http://gcc.gnu.org/gcc-4.9/changes.html), and Linaro supplies GCC
4.9.2:

$ g++ --version
g++ (Debian/Linaro 4.9.2-10) 4.9.2
Copyright (C) 2014 Free Software Foundation, Inc.

I'm wonder why the option is not being consumed by GCC. Are there any
ideas what I should be doing differently?

Thanks in advance.

Jeff
Jim Wilson
2016-07-20 21:33:30 UTC
Permalink
Post by Jeffrey Walton
I'm having trouble with ARMv8/Aarch64. One is an early Mustang server
ARMv8 implies 32-bit code (aarch32). Aaarch64 implies 64-bit code.
These are two different compilers, with two different sets of command
line options.
Post by Jeffrey Walton
$ g++ -DDEBUG -g3 -O0 -mfpu=neon-fp-armv8 -fPIC -pipe -c cryptlib.cpp
g++: error: unrecognized command line option ‘-mfpu=neon-fp-armv8’
GNUmakefile:753: recipe for target 'cryptlib.o' failed
-mfpu=neon-fp-armv8 is an arm (32-bit) compiler option. The aarch64
(64-bit) compiler will not accept it.

Because FP and Neon support is optional in the 32-bit arm
architecture, there are compiler options to enable fp and/or neon
support. Usually FP support is enabled by default for a linux distro,
but the neon support usually is not, and you can enable neon by using
this -mcpu=neon-fp-armv8 option if running 32-bit code on an ARMv8
architecture part.

Meanwhile, the aarch64 spec requires FP and ASIMD instruction support
in the linux ABI, so there are no options to enable them, they are on
by default. If you really want to disable them, you can do so by
using a -march= option, e.g. -march=aarch64+fp+simd enables them, and
-march=aarch64+nofp+nosimd disables them. However, if you disable fp
support, you will break the ABI, and your code may not compile or run,
so don't do that unless perhaps you have an embedded target, and have
your own OS build and your own ABI. or no code that uses FP You can
also enable/.disable crc (crypto) support this way, but a better way
is to use a -mcpu= option, and let gcc figure out if the target has
crc instructions.

See the aarch64 compiler docs here
https://gcc.gnu.org/onlinedocs/gcc/AArch64-Options.html#AArch64-Options

Jim
Jeffrey Walton
2016-07-20 22:04:02 UTC
Permalink
Post by Jim Wilson
Post by Jeffrey Walton
I'm having trouble with ARMv8/Aarch64. One is an early Mustang server
ARMv8 implies 32-bit code (aarch32). Aaarch64 implies 64-bit code.
These are two different compilers, with two different sets of command
line options.
Thanks Jim. According to ARM, ARMv8 is 64-bit
(http://www.arm.com/products/processors/armv8-architecture.php). Maybe
I'm parsing the page incorrectly?

(Note that I'm aware of Aarch32 execution environments on Aarch64. I'm
not trying for that test case at the moment).
Post by Jim Wilson
Post by Jeffrey Walton
$ g++ -DDEBUG -g3 -O0 -mfpu=neon-fp-armv8 -fPIC -pipe -c cryptlib.cpp
g++: error: unrecognized command line option ‘-mfpu=neon-fp-armv8’
GNUmakefile:753: recipe for target 'cryptlib.o' failed
-mfpu=neon-fp-armv8 is an arm (32-bit) compiler option. The aarch64
(64-bit) compiler will not accept it.
Because FP and Neon support is optional in the 32-bit arm
architecture, there are compiler options to enable fp and/or neon
support. Usually FP support is enabled by default for a linux distro,
but the neon support usually is not, and you can enable neon by using
this -mcpu=neon-fp-armv8 option if running 32-bit code on an ARMv8
architecture part.
OK, thanks. So is neon-fp-armv8 an Aarch32 execution environment option?
Post by Jim Wilson
Meanwhile, the aarch64 spec requires FP and ASIMD instruction support
in the linux ABI, so there are no options to enable them, they are on
by default.
Yeah, I was clear on asimd being ARM-64's equivalent to NEON and it
was enabled by default.
Post by Jim Wilson
If you really want to disable them, you can do so by
using a -march= option, e.g. -march=aarch64+fp+simd enables them, and
-march=aarch64+nofp+nosimd disables them. However, if you disable fp
support,
Oh, NO. We want to test under them. Sorry about the confusion.
Post by Jim Wilson
you will break the ABI, and your code may not compile or run,
so don't do that unless perhaps you have an embedded target, and have
your own OS build and your own ABI. or no code that uses FP You can
also enable/.disable crc (crypto) support this way, but a better way
is to use a -mcpu= option, and let gcc figure out if the target has
crc instructions.
See the aarch64 compiler docs here
https://gcc.gnu.org/onlinedocs/gcc/AArch64-Options.html#AArch64-Options
So it looks like the course of action is to simply remove it from
http://github.com/weidai11/cryptopp/blob/master/cryptest.sh#L874 . (It
was added recently because of the ML recommendation).

These ARM options are awful. I spent the better part of a day trying
to untangle the option combinations to ensure we are getting good test
coverage in a test script. I'd give my left arm device for a compiler
that provides -march=native or -mfpu=native and gets it right.

Jeff
Jim Wilson
2016-07-20 23:09:25 UTC
Permalink
Post by Jeffrey Walton
Thanks Jim. According to ARM, ARMv8 is 64-bit
(http://www.arm.com/products/processors/armv8-architecture.php). Maybe
I'm parsing the page incorrectly?
The armv8 architecture spec has both aarch32 (32-bit) and aarch64
(64-bit) support. However, for over two decades, we have had an arm
gcc port that only emits 32-bit code. If we rename that to aarch32,
we break two decades of backward compatibility. Hence, for gcc, arm*
always means 32-bit. If you mean 64-bit, then you have to use
aarch64. Since aarch64 is not a simple extension of the armv7
architecture to 64-bits, but rather a new architecture with some
backward compatibility, we actually have two different compiler ports
for armv8 support, the old arm compiler that emits 32-bit code only
and the new aarch64 port that emits 64-bit code only. Both are
capable of emitting ARMv8 code. Only the arm port can emit ARMv7
code.

Similarly, the kernel uses "arm" and "arm64", because they were
unwilling to redefine what armvX means, and they were unwilling to
rename the arm port to aarch32. Arm and arm64 are distinctly
different kernel ports.
Post by Jeffrey Walton
OK, thanks. So is neon-fp-armv8 an Aarch32 execution environment option?
I think "execution environment" is the wrong way to look at this.
There are two different compilers. Arm and aarch64 are treated like
two separate architectures, each with its own separate compiler port.
It is possible to run an arm cross aarch64 compiler in the aarch32
execution environment, and it is possible to run an aarch64 cross arm
compiler in the aarch64 execution environment. The important bit is
which compiler you are using, not your execution environment.

-mfpu=neon-fp-armv8 is an option accepted by the arm compiler. it is
not accepted by the aarch64 compiler. if you use the
-mfpu=neon-fp-armv8 option with the arm compiler, that tells it to
emit Neon and FP code using the armv8 architecture.
Post by Jeffrey Walton
So it looks like the course of action is to simply remove it from
http://github.com/weidai11/cryptopp/blob/master/cryptest.sh#L874 . (It
was added recently because of the ML recommendation).
It should be moved from the IS_ARM64 section to the IS_ARM32 section.
it is an arm option, not an aarch64 option. The code as written will
only work if you are running 32-bit code on a 64-bit kernel, but that
should be OK. You already have support for the 32-bit kernel in
checking for neon. So if you have both the neon and the asimd checks,
then you are supporting code running on both 32-bit and 64-bit
kernels. This assumes that no cross compiler will be used, as the
/proc/cpuinfo check won't work in that case.
Post by Jeffrey Walton
These ARM options are awful. I spent the better part of a day trying
to untangle the option combinations to ensure we are getting good test
coverage in a test script. I'd give my left arm device for a compiler
that provides -march=native or -mfpu=native and gets it right.
Both the arm and aarch64 compilers support -march=native, but this
doesn't solve the arm FPU problem. For arm, it is possible to run a
soft-float rootfs on a hard float part, so we can't tell whether to
emit FP code based on the CPU. A reasonable default must be built
into the compiler, and if you want something different, you have to
request it on the command line. For aarch64, FP and SIMD support is
required, so it is just a question of whether crc and/or crypto is
supported, and -march=native can handle that as there is no ABI change
when enabling/disabling them.

Jim
Richard Earnshaw
2016-07-21 08:53:22 UTC
Permalink
Post by Jim Wilson
Post by Jeffrey Walton
I'm having trouble with ARMv8/Aarch64. One is an early Mustang server
ARMv8 implies 32-bit code (aarch32). Aaarch64 implies 64-bit code.
These are two different compilers, with two different sets of command
line options.
Er, no. ARMv8 (pedantically ARMv8-A, since there are also ARMv8-R and
ARMv8-M specifications as well) is an architecture, not an ISA. The
ARMv8 architecture defines two execution modes: AArch32 and AArch64.
The AArch32 execution mode further has to states with separate ISAs: A32
and T32, more traditionally known as ARM and Thumb states.

GCC has two separate compilers for ARMv8. One handles the AArch32
execution mode (configurations based arm-*-* for legacy reasons) and
the other AArch64 (configurations based on aarch64-*-*).

The -mfpu option only applies to the AArch32 compiler.

R.
Post by Jim Wilson
Post by Jeffrey Walton
$ g++ -DDEBUG -g3 -O0 -mfpu=neon-fp-armv8 -fPIC -pipe -c cryptlib.cpp
g++: error: unrecognized command line option ‘-mfpu=neon-fp-armv8’
GNUmakefile:753: recipe for target 'cryptlib.o' failed
-mfpu=neon-fp-armv8 is an arm (32-bit) compiler option. The aarch64
(64-bit) compiler will not accept it.
Because FP and Neon support is optional in the 32-bit arm
architecture, there are compiler options to enable fp and/or neon
support. Usually FP support is enabled by default for a linux distro,
but the neon support usually is not, and you can enable neon by using
this -mcpu=neon-fp-armv8 option if running 32-bit code on an ARMv8
architecture part.
Meanwhile, the aarch64 spec requires FP and ASIMD instruction support
in the linux ABI, so there are no options to enable them, they are on
by default. If you really want to disable them, you can do so by
using a -march= option, e.g. -march=aarch64+fp+simd enables them, and
-march=aarch64+nofp+nosimd disables them. However, if you disable fp
support, you will break the ABI, and your code may not compile or run,
so don't do that unless perhaps you have an embedded target, and have
your own OS build and your own ABI. or no code that uses FP You can
also enable/.disable crc (crypto) support this way, but a better way
is to use a -mcpu= option, and let gcc figure out if the target has
crc instructions.
See the aarch64 compiler docs here
https://gcc.gnu.org/onlinedocs/gcc/AArch64-Options.html#AArch64-Options
Jim
_______________________________________________
linaro-toolchain mailing list
https://lists.linaro.org/mailman/listinfo/linaro-toolchain
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
Jim Wilson
2016-07-21 15:11:59 UTC
Permalink
On Thu, Jul 21, 2016 at 1:53 AM, Richard Earnshaw
Post by Richard Earnshaw
Post by Jim Wilson
Post by Jeffrey Walton
I'm having trouble with ARMv8/Aarch64. One is an early Mustang server
ARMv8 implies 32-bit code (aarch32). Aaarch64 implies 64-bit code.
These are two different compilers, with two different sets of command
line options.
Er, no. ARMv8 (pedantically ARMv8-A, since there are also ARMv8-R and
ARMv8-M specifications as well) is an architecture, not an ISA.
I think you are confusing the issue. We are talking about gcc here,
not ARM documentation. In gcc, arm* means 32-bit code. An
armv8-linux-gnu compiler is a 32-bit compiler. If I run uname -a, and
see armv8a, I have a 32-bit user space. Etc.

The original poster is well aware that ARMv8 is an architecture, with
32-bit and 64-bti execution modes. What he wasn't aware of was that
the arm and aarch64 compilers are separate, and that if someone
mentions an armv8 compiler on a gcc mailing list, then they are
talking about the 32-bit arm* compiler, not the 64-bit aarch64
compiler.

I did mention that both the arm and aarch64 compilers can emit ARMv8
architecture code.

Jim

Loading...