This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
ARM's Changing Call Used Registers Causes Weird Bugs
- From: lin zuojian <manjian2006 at gmail dot com>
- To: gcc at gcc dot gnu dot org
- Date: Mon, 8 Jun 2015 16:07:13 +0800
- Subject: ARM's Changing Call Used Registers Causes Weird Bugs
- Authentication-results: sourceware.org; auth=none
Hi,
in arm.c
static void
arm_conditional_register_usage (void)
...
if (TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP)
{
/* VFPv3 registers are disabled when earlier VFP
versions are selected due to the definition of
LAST_VFP_REGNUM. */
for (regno = FIRST_VFP_REGNUM;
regno <= LAST_VFP_REGNUM; ++ regno)
{
fixed_regs[regno] = 0;
call_used_regs[regno] = regno < FIRST_VFP_REGNUM + 16
|| regno >= FIRST_VFP_REGNUM + 32;
}
}
these lines will change the called used registers, when using
compiler flags like: -mfpu=neon.
That causes weird bugs. Consider the situation in Android ARM
architecture: I have a shared object supposed to run in a neon cpu,
and -mfpu=neon added. But the system is not compiled using this
flag. So when calling the system's library, my code will risk using
the clobbered d8-d16.
The example will be:
while (true) {
struct my_struct s = {0}; // my_struct is 8 bytes long.
call_system_library...
}
in this example. d8 is used to initialize s to zero. The assembly
code like:
push {d8} // because d8 is not call used.
// the loop header
vmov.i32 d8, #0
// the loop body
vstr d8, &s
bl system_library
b loop_body
d8 is clobbered after branch link to system library, so the second
loop will initialize s to random value, which causes crash.
So I am forced to remove the -mfpu=neon for compatibility. My
question is whether the gcc code show above confront to ARM
standard. If so, why ARM make such a weird standard.
--
Lin Zuojian