[fpc-devel] Arm Thumb2 - Stellaris status

Jeppe Græsdal Johansen jjohan07 at student.aau.dk
Sat Aug 20 23:14:35 CEST 2011


Den 20-08-2011 22:24, David Welch skrev:
>
> thumb2 is an extension to thumb not arm, you can mix thumb and arm in 
> T variants like the v4T v5T and anything after that v6 on up, except 
> for the cortex-m variants which are thumb+thumb2 only and cannot 
> execute ARM 32 bit instructions (yes thumb2 32 bit thumb extensions 
> but nothing from the ARM instruction set).
>
> Here is an example of the problem I am seeing:
>
> took a clean copy from svn
>
> svn co http://svn.freepascal.org/svn/fpc/trunk fpc
>
> cd fpc
>
> make clean buildbase installbase CROSSINSTALL=1 OS_TARGET=embedded 
> CPU_TARGET=arm INSTALL_PREFIX=/fpcarm
>
>
> ---- test.pp ----
> procedure Wait(d : dword);
>   begin
>   while d<>0 do
>     dec(d);
> end;
>
> begin
>
>   while true do
>     begin
>         Wait($20000);
>     end;
> end.
> ---- test.pp ----
>
>
> ./compiler/ppcrossarm -Parm -Tembedded -Wpstm32f103re -Cpcortexm3 test.pp
> Free Pascal Compiler version 2.7.1 [2011/08/20] for arm
> Copyright (c) 1993-2011 by Florian Klaempfl and others
> Target OS: Embedded
> Compiling test.pp
> Assembling program
> Linking test
> /opt/embarm/arm-embedded-ld: warning: library search path 
> "/usr/local/lib/fpc/2.7.1/units/arm-embedded/rtl/" is unsafe for 
> cross-compilation
> 14 lines compiled, 0.0 sec
>
> then dumped the binary:
>
> 08000000 <_START-0x158>:
>  8000000:    2000fffc     strdcs    pc, [r0], -ip
>  8000004:    08000405     stmdaeq    r0, {r0, r2, sl}
>  8000008:    08000405     stmdaeq    r0, {r0, r2, sl}
>  800000c:    08000405     stmdaeq    r0, {r0, r2, sl}
>  8000010:    08000405     stmdaeq    r0, {r0, r2, sl}
>  8000014:    08000405     stmdaeq    r0, {r0, r2, sl}
>  8000018:    08000405     stmdaeq    r0, {r0, r2, sl}
> ...
> 08000194 <PASCALMAIN>:
>  8000194:    46ec          mov    ip, sp
>  8000196:    e92d 4800     stmdb    sp!, {fp, lr}
>  800019a:    f1ac 0b04     sub.w    fp, ip, #4
>  800019e:    b08a          sub    sp, #40    ; 0x28
>  80001a0:    f000 f844     bl    800022c <FPC_INITIALIZEUNITS>
>  80001a4:    e004          b.n    80001b0 <PASCALMAIN+0x1c>
>  80001a6:    bf00          nop
>  80001a8:    f44f 3000     mov.w    r0, #131072    ; 0x20000
>  80001ac:    f7ff ffd8     bl    8000160 <P$PROGRAM_WAIT$LONGWORD>
>  80001b0:    e7fa          b.n    80001a8 <PASCALMAIN+0x14>
>  80001b2:    f000 f8ff     bl    80003b4 <FPC_DO_EXIT>
>  80001b6:    46dd          mov    sp, fp
>  80001b8:    b001          add    sp, #4
>  80001ba:    e91d 8800     ldmdb    sp, {fp, pc}
>  80001be:    bf00          nop
> ...
> 08000404 <STM32F103__FPC_START>:
>  8000404:    e59f103c     ldr    r1, [pc, #60]    ; 8000448 
> <STM32F103__FPC_START+0x44>
>  8000408:    e59f203c     ldr    r2, [pc, #60]    ; 800044c 
> <STM32F103__FPC_START+0x48>
>  800040c:    e59f303c     ldr    r3, [pc, #60]    ; 8000450 
> <STM32F103__FPC_START+0x4c>
>  8000410:    e1520003     cmp    r2, r3
>  8000414:    94910004     ldrls    r0, [r1], #4
>
>
> First off 0x08000405 implies a thumb target but it is not thumb code, 
> it is arm code so 0x08000404 would be correct but that is still wrong 
> because cores with that vector table (cortex-m) cannot execute arm 
> instructions.
It implies thumb mode, which is the only valid mode on Cortex-M3
> Looking at that first instruction in the reset handler
>
> 08000404 <STM32F103__FPC_START>:
>  8000404:    e59f103c     ldr    r1, [pc, #60]    ; 8000448 
> <STM32F103__FPC_START+0x44>
The problem is that you are using an RTL built for ARM. That's what the 
warning is about. You installed the compiler in /fpcarm, but it's using 
units from /usr/local/lib/fpc/2.7.1/units/arm-embedded/rtl/

A correctly compiled unit would look like this:
00000000 <STM32F103__FPC_START>:
    0:   f8df 1034       ldr.w   r1, [pc, #52]   ; 38 
<STM32F103__FPC_START+0x38>
    4:   4a0d            ldr     r2, [pc, #52]   ; (3c 
<STM32F103__FPC_START+0x3c>)
    6:   4b0e            ldr     r3, [pc, #56]   ; (40 
<STM32F103__FPC_START+0x40>)
    8:   429a            cmp     r2, r3
    a:   bf9e            ittt    ls
>        IPUBWL
> 1110 01011001 r15, r1, 0x03C
>
> And that was properly decoded by objdump, immediate offset 
> rn+offset12, load, word sized, etc.
> PC is 0x800040C at that time so load address is 0x800040C+0x03C = 
> 0x8000448
>
> You can tell both by 32 bit numbers in the dump but the dominance of 
> an 0xE as the first nibble also implies these are arm instructions not 
> thumb (need to see a long chunk of code to see the pattern).  Had they 
> been thumb instructions but decoded wrong by the disassembler then the 
> first and fourth nibbles would have been dominated by like 6's and 7's 
> or at least would stand out compared to the other
> nibbles.
>
> if we decode this as thumb/thumb2
>
> 0xE59F
>
> //B(2) unconditional branch
>     if((inst&0xF800)==0xE000)
>     {
>         rb=(inst>>0)&0x7FF;
>         if(rb&(1<<10)) rb|=(~0)<<11;
>         rb<<=1;
>         rb+=pc;
>         rb+=2;
>         write_register(15,rb);
>         return(0);
>     }
>
> 1110010110011111
>
> 11100 10110011111
>
> ...11111110110011111
> ...111111101100111110
> ...11 1111 1011 0011 1110
>
> pc = 0x405+4 = 0x409
> pc + 0x...FFB3E =
> 0x409 - (0x4C1 + 1) =  0x7FFFF47
>
> Unconditional branch to 0x07FFFF47  so it is a valid instruction, but 
> doesnt make much sense
>
>
> This does though, the start code from stm32f103.pp
>
>     .globl _start
>     .text
> _start:
>
>     // Copy initialized data to ram
>     ldr r1,.L_etext
>     ldr r2,.L_data
>     ldr r3,.L_edata
> .Lcopyloop:
>     cmp r2,r3
>     ittt ls
>     ldrls r0,[r1],#4
>     strls r0,[r2],#4
>     bls .Lcopyloop
>
> The instructions the assembler was able to encode it did:
>
>  8000404:    e59f103c     ldr    r1, [pc, #60]
>  8000408:    e59f203c     ldr    r2, [pc, #60]
>  800040c:    e59f303c     ldr    r3, [pc, #60]
>  8000410:    e1520003     cmp    r2, r3
>  8000414:    94910004     ldrls    r0, [r1], #4
> ....
>  8000448:    08000468     stmdaeq    r0, {r3, r5, r6, sl}
>  800044c:    20000000     andcs    r0, r0, r0
>  8000450:    20000048     andcs    r0, r0, r8, asr
>
>
> 0x08000468 is the word aligned address for the end of the text segment 
> and 0x20000000 the beginning of text for this example so that is 
> correct as well.
>
> and interestingly the ittt ls instruction is discarded.
>
> The code from stm32f103.pp
>
>     ldr r1,.L_etext
>     ldr r2,.L_data
>     ldr r3,.L_edata
> .Lcopyloop:
>     cmp r2,r3
>     ittt ls
>     ldrls r0,[r1],#4
>     strls r0,[r2],#4
>     bls .Lcopyloop
>
> when assembled should look like this
>
> 00000000 <.text>:
>    0:    4904          ldr    r1, [pc, #16]    ; (14 <.text+0x14>)
>    2:    4a05          ldr    r2, [pc, #20]    ; (18 <.text+0x18>)
>    4:    4b05          ldr    r3, [pc, #20]    ; (1c <.text+0x1c>)
>    6:    429a          cmp    r2, r3
>    8:    bf9e          ittt    ls
>    a:    f851 0b04     ldrls.w    r0, [r1], #4
>    e:    f842 0b04     strls.w    r0, [r2], #4
>   12:    e7f8          bls.n    6 <.text+0x6>
>   14:    00000001     andeq    r0, r0, r1
>   18:    00000002     andeq    r0, r0, r2
>   1c:    00000003     andeq    r0, r0, r3
>
> with different addresses of course...when assembled for thumb.
>
> So it doesnt look like that is happening
>
> Pascal main is definitely thumb+thumb2.
>
> 08000194 <PASCALMAIN>:
>  8000194:    46ec          mov    ip, sp
>  8000196:    e92d 4800     stmdb    sp!, {fp, lr}
>  800019a:    f1ac 0b04     sub.w    fp, ip, #4
>  800019e:    b08a          sub    sp, #40    ; 0x28
>
> More info about my setup:
>
> svn info
>
>  URL: http://svn.freepascal.org/svn/fpc/trunk
> Repository Root: http://svn.freepascal.org/svn/fpc
> Repository UUID: 3ad0048d-3df7-0310-abae-a5850022a9f2
> Revision: 18278
> Node Kind: directory
> Schedule: normal
> Last Changed Author: florian
> Last Changed Rev: 18278
> Last Changed Date: 2011-08-19 18:06:52 -0400 (Fri, 19 Aug 2011)
>
> Ubuntu 10.4 or something like that 64 bit host.
> Linux dwelch-desktop 2.6.32-33-generic #72-Ubuntu SMP Fri Jul 29 
> 21:07:13 UTC 2011 x86_64 GNU/Linux
>
> fpc is what you apt-get so probably a little behind but stable in the 
> eyes of ubuntu or debian.
>
>  fpc
> Free Pascal Compiler version 2.4.0-2ubuntu1.10.04 [2011/06/17] for x86_64
> Copyright (c) 1993-2009 by Florian Klaempfl
> /usr/lib/fpc/2.4.0/ppcx64 [options] <inputfile> [options]
> Put + after a boolean switch option to enable it, - to di
>
> GNU assembler (Sourcery G++ Lite 2011.03-42) 2.20.51.20100809
> Copyright 2010 Free Software Foundation, Inc.
> This program is free software; you may redistribute it under the terms of
> the GNU General Public License version 3 or later.
> This program has absolutely no warranty.
> This assembler was configured for a target of `arm-none-eabi'.
>
>
>
>
> So what did I do wrong?  and what is the unsafe thing about?
>
> Thanks,
> David
>
>
>
> On 08/20/2011 11:23 AM, Jeppe Græsdal Johansen wrote:
>> Den 20-08-2011 16:46, David Welch skrev:
>>> I was hoping for thumb support but I now see that the choices are
>>> limited to arm and thumb+thumb2 (without any separation between thumb
>>> and thumb2). Actually thumb2 wasnt working for me, I got an arm+thumb2
>>> mix, so I will ride this along for a while and see what comes up,
>>> otherwise limit my use to ARM targets, or start working on a thumb
>>> backend. Adding backends as well as arm embedded are of interest to me
>>> so I may work on a little of both.
>> Why thumb support? The choices are indeed currently only either ARM or
>> Thumb2(which is Thumb+32 bit extensions). Thumb2 is a variable length
>> instruction set that looks like an arm+thumb mix, so I guarantee you
>> that it works :)
>> _______________________________________________
>> fpc-devel maillist - fpc-devel at lists.freepascal.org
>> http://lists.freepascal.org/mailman/listinfo/fpc-devel
>> .
>
> _______________________________________________
> fpc-devel maillist  - fpc-devel at lists.freepascal.org
> http://lists.freepascal.org/mailman/listinfo/fpc-devel





More information about the fpc-devel mailing list