[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