[fpc-devel] Capability CPUARM_HAS_BLX_LABEL with ARM instruction set
Garry Wood
garry at softoz.com.au
Tue Dec 15 01:26:11 CET 2015
Hello,
I have been working on some embedded (no OS) development on ARMv6 and ARMv7 (Raspberry Pi and Raspberry Pi 2) using FPC 3.1.1 trunk.
Because these devices have a fairly large amount of memory I have been using ARM instruction set (-CIARM option) to simplify the assembler code required for the low level interfaces, however early on I noticed that if I specify the options -CpARMV7A (or -CpARMV6) and -CIARM I end up with code that doesn't work.
I traced the problem to the use of BLX <Label> instructions which according to the ARM documentation seem to always causes an unconditional change to Thumb state. If I remove the CPUARM_HAS_BLX_LABEL capability and rebuild the compiler the code produced uses only BL <Label> and always works correctly. There seems to be no problem with BLX <Register> or BX <Register> instructions which use bit[0] of the register to determine the target state.
There appear to be only two places in the compiler and RTL code where CPUARM_HAS_BLX_LABEL and ARM state needs to be handled, these are:
\source\compiler\arm\cgcpu.pas
Which in tbasecgarm.a_call_name has something like
if (CPUARM_HAS_BLX_LABEL in cpu_capabilities[current_settings.cputype]) and
{ WinCE GNU AS (not sure if this applies in general) does not support BLX imm }
(target_info.system<>system_arm_wince) then
branchopcode:=A_BLX
else
branchopcode:=A_BL;
This could easily be changed to
if (CPUARM_HAS_BLX_LABEL in cpu_capabilities[current_settings.cputype]) and
{ WinCE GNU AS (not sure if this applies in general) does not support BLX imm }
(target_info.system<>system_arm_wince) and
(current_settings.instructionset <> is_arm) then
branchopcode:=A_BLX
else
branchopcode:=A_BL;
to account for the ARM state.
The other occurrence is in the assembler code in \source\rtl\arm\arm.inc for fpc_ansistr_decr_ref which has
{$if defined(CPUARM_HAS_BX) and not(defined(WINCE))}
blx InterLockedDecrement
This should probably be changed to defined(CPUARM_HAS_BLX_LABEL) instead but that doesn't deal with the selected instruction set (ARM or Thumb). Obviously the CPU capabilities are available as defines at this point but I cannot actually find anywhere that the IS_ARM / IS_THUMB settings also end up as defines.
Before I go ahead and log this as a bug report is there anyone who can comment on whether :
a) There is something I am misunderstanding in the ARM documentation about BLX <Label> and the switch to Thumb state?
b) How the use of BLX <Label> in \rtl\arm\arm.inc might be resolved (is there actually a define that reflects ARM or Thumb state selection)?
One more thing, just wanted to give a big congratulations to the FPC dev team. I have been working on this project for several months and have a fully working embedded core including pre-emptive threading, lock primitives, multicore support, memory management, hardware exceptions, interrupt handling, DMA, USB, filesystem, network etc which is 100% Free Pascal and this is the only issue I have encountered that I could directly trace to FPC itself. Thanks to you all for such a powerful compiler!
Thanks,
Garry Wood.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-devel/attachments/20151215/bfd09672/attachment.html>
More information about the fpc-devel
mailing list