[fpc-devel] Arm Thumb2 - Stellaris status

David Welch dwelch at dwelch.com
Sat Aug 20 22:24:34 CEST 2011

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 

---- test.pp ----
procedure Wait(d : dword);
   while d<>0 do


   while true do
---- 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 
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 

Looking at that first instruction in the reset handler

08000404 <STM32F103__FPC_START>:
  8000404:	e59f103c 	ldr	r1, [pc, #60]	; 8000448 <STM32F103__FPC_START+0x44>

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

if we decode this as thumb/thumb2


//B(2) unconditional branch
         if(rb&(1<<10)) rb|=(~0)<<11;


11100 10110011111

...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
	// Copy initialized data to ram
	ldr r1,.L_etext
	ldr r2,.L_data
	ldr r3,.L_edata
	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
     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.

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)
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?


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
> .

More information about the fpc-devel mailing list