ARM GCC inline assembly error on %w operand - gcc

I have an ARMv8 inline assembly segment:
/* get leading 0 of cache ways */
__asm__ __volatile__
(
"CLZ %w[shift], %w[maxWay] \n"
: [shift] "=r" (uiShift)
: [maxWay] "r" (uiMaxWay)
);
When compile by ARM GCC compiler:
Interestingly, if I compile with Linaro compiler, then there is no problem.
Is there a problem in ARM GCC compiler, or in my code?

Unlike x86 where the same compiler can produce x86-32 or x86-64 code with -m32 and -m64, you need a separate build of gcc for ARM vs. AArch64.
ARM gcc accepts -march=armv8-a, but it's still compiling in 32-bit ARM mode, not AArch64.
I can reproduce your problem on the Godbolt compiler explorer with AArch64 gcc and ARM gcc. (And I included an example that uses __builtin_clz(uiShift) instead of inline asm, so it compiles to a clz instruction on either architecture.)
BTW, you could have left out the w size override on both operands, and simply use unsigned int for the input and output. Then the same inline asm would work with both ARM and AArch64. (But __builtin_clz is still better, because the compiler understands what it does. e.g. it knows the result is in the range 0..31, which may enable some optimizations.)

Related

GCC equivalent of armclang --target=aarch64-arm-none-eabi compiler option

Hi I am trying to find out the GCC equivalent of armclang compiler option --target=aarch64-arm-none-eabi which instructs the compiler to generate A64 instructions?

Cross compiling - Error: selected processor does not support `fmrx r3,fpexc' in ARM mode - Beaglebone

I'm trying to cross-compile a file to flash into the Beaglebone Black.
All works fine, but if I try to enable the FPU with
#define set_en_bit_in_fpexc() do { \
int dummy; \
__asm__ __volatile__ ("fmrx %0,fpexc\n\t" \
"orr %0,%0,#0x40000000\n\t" \
"fmxr fpexc,%0" : "=r" (dummy) : :); \
} while (0)
I get the following error
Error: selected processor does not support `fmrx r3,fpexc' in ARM mode
Error: selected processor does not support `fmxr fpexc,r3' in ARM mode
I also tried with thumb mode, but I get the same errors.
Of course if I remove the part of the code that initialize the FPU it works fine.
Why I get those errors?
Makefile
[...]
CROSSPATH?=/usr/bin
CROSSPFX=$(CROSSPATH)/arm-none-eabi-
CC=$(CROSSPFX)gcc
AS=$(CROSSPFX)as
LD=$(CROSSPFX)ld
NM=$(CROSSPFX)nm
OBJCOPY=$(CROSSPFX)objcopy
OBJDUMP=$(CROSSPFX)objdump
CFLAGS=-Wall -Wextra -O2 -ffreestanding
ARCHFLAGS=-mcpu=cortex-a8 -march=armv7-a -mfpu=neon
CCARCHFLAGS=$(ARCHFLAGS) -marm
[...]
I'm on Arch, kernel 4.8.1
P.S. My professor uses the linaro cross-compiler and it works just fine
Most of the Linaro toolchains are configured for ARMv7 hard-float by default (certainly the Linux ones, I'm less sure about the bare-metal ones). Looking at the configuration of the arm-none-eabi toolchain as packaged by Arch, I surmise it's just using the GCC defaults for things like that, which implies something like ARMv4t, and crucially, soft-float ABI.
Whilst the -mfpu option controls code generation in terms of which floating-point instructions may be used, apparently it's the float ABI which controls whether it'll let you do things which really only make sense on a hardware FPU, rather than under floating-point emulation.
When it's not configured by default, you need to explicitly select a floating-point ABI implying an actual hardware FPU, i.e. -mfloat-abi=hard (or -mfloat-abi=softfp, but there's really no reason to use that unless you need to link against other soft-float code).
-mfpu=vfpv3-d16 -mfloat-abi=hard
Just to give a more direct solution, I had to add -mfpu=vfpv3-d16.
Test code a.S:
fmrx r2, fpscr
Working command:
sudo apt-get install binutils-arm-linux-gnueabihf
arm-linux-gnueabihf-as -mfpu=vfpv3-d16 -mfloat-abi=hard a.S
Note that -mfloat-abi=hard is enabled by default on this particular build of arm-linux-gnueabihf-as, and could be omitted.
The default value of float-abi likely depends on -msoft-float vs -mhard-float controlled at GCC build time with:
./configure --with-float=soft
as documented at: https://gcc.gnu.org/install/configure.html You can get the flags used for your toolchain build with gcc -v as mentioned at: What configure options were used when building gcc / libstdc++? I could not however easily determine its default value if not given.
You may also be interested in -mfloat-abi=softfp which can produce hard floats for the executable, but generate soft function calls: ARM compilation error, VFP registered used by executable, not object file
The possible values of -mfpu= can be found at: https://gcc.gnu.org/onlinedocs/gcc-7.2.0/gcc/ARM-Options.html#ARM-Options
Also note that FMRX is the pre-UAL syntax for VMRS which the newer recommended syntax, see also: Are ARM instructuons SWI and SVC exactly same thing?
Tested on Ubuntu 16.04, arm-linux-gnueabihf-as 2.26.1.

Compiling assembly code for aarch64

I have generated an assembly file try.s with aarch64 instruction set.I want to compile this on an ARM8 (aarch64 processor) running ubuntu.
my native compiler is gcc(4.8) and i use the following command to compile
gcc -o try.o try.s
I am getting the following errors
Error : ARM register expected -- mov x10,x0
It seems like the aarch4 registers are not being recognized although i thought gcc 4.8 supported aarch64. Can someone tell me what am i missing or is there any special option i should include.Or suggest me a native compiler(not cross-compilers) for doing aarch64.I would also like to use gdb to debug this natively.
gcc is for a 32b targets. 'Xn' registers are not defined for a aarch32 instruction set. That's what compiler tells you.
Right toolchain is aarch64-elf-gcc.
PS: that's a good idea to make asm file extention .S (capital s)

cannot compile C program with GCC on Mac and -masm=intel

I'm trying to compile a C program that has some inline assembly code in Intel format. I'm using GCC 4.9 (installed via Homebrew) on Mac 10.9, and the compiler flags:
gcc-4.9 -m32 -masm=intel -std=gnu99 get_rating.c
Unfortunately I get an error:
error: -masm=intel not supported in this configuration
I've tried many different combinations of the flags, but I keep getting that error. I can't leave out the -masm=intel flag, because the code I'm trying to compile uses Intel.
How can I compile the program? Is it at all possible on my Mac (version 10.9) or do I need to run a virtual machine?
The GCC docs state that Darwin does not support intel, so it seems you are out of luck with the direct approach. Virtual machine as you suggested, cross compiling, converting the assembler to att, and replacing the assembler with C are among your options - which is best for you you'll have to figure out.
HTH

How can I use gcc to compile x86 assembly code on an x64 computer

For a school assignment I have to write x86 assembly code, except I can't use gcc to compile it since my computer is an x64 machine, and gcc is only excpecting x86 code. Is there a command that'll make gcc accept it x86 assembly code? Thanks
P.S. I know my code is valid since it compiles just fine on x86 machines.
Just pass the -m32 option to gcc.

Resources