Page 1 of 1

ARM assembler Thumb instruction set

Posted: Thu Mar 29, 2018 4:39 pm
by crumb_er
Hi, I need to use only Thumb instruction set for a project but when i try to compile a simple hello world c program with the command
gcc hello.c -S -mthumb I have the error :

Code: Select all

hello.c: In function ‘main’:
hello.c:6:1: sorry, unimplemented: Thumb-1 hard-float VFP ABI
 {
 ^
 
Do you know what's the error or if is there another way to do this?

I use a raspberry pi zero w with raspbian.

Re: ARM assembler Thumb instruction set

Posted: Thu Mar 29, 2018 6:12 pm
by jahboater
You cant.
The Pi Zero only supports Thumb1 (16 bit only) which is too limited for a whole program. You might possibly be able to hand assemble a small function, I don't know. You would need to think about thumb inter working as well.

If you tried on a Pi2 or Pi3, -mthumb works fine, because that is Thumb2 which is a complete instruction set.
Thumb2 is mixed 16 and 32 bit instructions and gives a huge space saving.
There are some ARM cpu's than can only execute Thumb2.
There are no issues with inter working because the entire program can be in thumb2.

Re: ARM assembler Thumb instruction set

Posted: Thu Mar 29, 2018 7:09 pm
by Paeryn
It's not a case of Thumb-1 being too limited for a whole program, more a case that you cannot access the VFP unit from Thumb-1 code. GCC is complaining because Thumb-1 and the hard-float ABI are incompatible.

Edit:
If Thumb-2 is okay (so RPi 2 & 3 only) you can tell GCC that you are targeting an A7 or A53

Code: Select all

gcc hello.c -S -mthumb -mcpu=cortex-a7
If you need Thumb-1 then you have to tell gcc that you want to target the soft-float ABI as well,

Code: Select all

gcc hello.c -S -mthumb -mfloat-abi=soft
But none of the libraries Raspbian comes with will link as they all target hard-float and pretty much any use of the system headers will fail too as the appropriate stubs header won't be found.

Re: ARM assembler Thumb instruction set

Posted: Fri Mar 30, 2018 6:48 am
by jahboater
Could I ask the OP why they want thumb on a Pi Zero?

You can get quite small C programs with: -Os -s
and some careful programming.

I used to use thumb2 on the Pi2 all the time as it gave a 25% reduction in program size with no loss of speed.
But with ARMv8 (new Pi2 and Pi3's) I started to get warnings that bits of it are deprecated (32 bit insns in IT blocks), so I have stopped using it.

Edit:
You can lose a few more bytes with

strip -p -R .comment -R .gnu.version -s <myprog>

Re: ARM assembler Thumb instruction set

Posted: Fri Mar 30, 2018 9:19 am
by Heater
That's odd. I have been using gcc since forever and never heard of the -s option. Had to check. Took me a while to find it. Seems it's been obsolete for ages.

I always used the strip command instead.

That only shrinks the executable file size by removing symbols. The memory usage at run time is the same. I don't bother when we have gigs of file system space.

I'm not sure there is much point in saving 25% memory usage with thumb code. For most of my programs that is only a tiny saving of the system memory saved. And programs often use a lot more data memory that code space.

Thumb instructions were intended for very memory limited ARM micro-controllers.

Re: ARM assembler Thumb instruction set

Posted: Fri Mar 30, 2018 12:19 pm
by jahboater
Heater wrote:
Fri Mar 30, 2018 9:19 am
That's odd. I have been using gcc since forever and never heard of the -s option. Had to check. Took me a while to find it. Seems it's been obsolete for ages.
Its been around on various C compilers since the dawn of time.

The man page for gcc just says this:

Code: Select all

-s  Remove all symbol table and relocation information from the executable.
Where did you read it is obsolete? Thats a new one on me!
I'm sure the compiler driver just calls strip.
Thumb instructions were intended for very memory limited ARM micro-controllers.
Yes I agree, certainly for thumb1 anyway. Thumb2 is much more useful because it has all the resources of the 32-bit instructions available too including NEON.

Re: ARM assembler Thumb instruction set

Posted: Fri Mar 30, 2018 12:22 pm
by jahboater
Heater wrote:
Fri Mar 30, 2018 9:19 am
I'm not sure there is much point in saving 25% memory usage with thumb code. For most of my programs that is only a tiny saving of the system memory saved. And programs often use a lot more data memory that code space.
Yes.
I just did a (very) rough calculation
1000 lines of my C code produces 5-6K of binary executable.
My Pi Zero has 406M of free memory, so thats (roughly) equivalent to 74 million lines of C.
Plenty of room!

Re: ARM assembler Thumb instruction set

Posted: Fri Mar 30, 2018 12:47 pm
by Heater
The -s option going obsolete might only be a mac os linker thing:

$ g++ hello.cc -Wall -std=c++0x -o test -Wl,-s
$ ld: warning: option -s is obsolete and being ignored

There is a discussion of it here:
https://stackoverflow.com/questions/740 ... -ignored-c

There is no such warning for me on any machine or gcc I have.

All in all it's hard to find anyone using -s when googling around. I have never actually seen anyone use it. That's probably why I never heard of it.

Re: ARM assembler Thumb instruction set

Posted: Fri Mar 30, 2018 12:53 pm
by crumb_er
Heater wrote:
Fri Mar 30, 2018 9:19 am
That's odd. I have been using gcc since forever and never heard of the -s option. Had to check. Took me a while to find it. Seems it's been obsolete for ages.
The S is uppercase in -S option.
From gcc documentation:
-S Compile only; do not assemble or link.
It generates a file .s with the assembler code.

Re: ARM assembler Thumb instruction set

Posted: Fri Mar 30, 2018 12:59 pm
by jahboater
Heater wrote:
Fri Mar 30, 2018 12:47 pm
The -s option going obsolete might only be a mac os linker thing:

$ g++ hello.cc -Wall -std=c++0x -o test -Wl,-s
$ ld: warning: option -s is obsolete and being ignored
Yes, that is a linker message - nothing at all to do with the compiler.
Why did they do "-Wl,s" ?? which passes the option directly to the linker, instead of just adding "-s" to the compiler options. I do vaguely remember this as yet another mac os nuisance from long ago.

The GNU linker man page says:

Code: Select all

       -s
       --strip-all
           Omit all symbol information from the output file.

       -S
       --strip-debug
           Omit debugger symbol information (but not all symbols) from the output file.

Re: ARM assembler Thumb instruction set

Posted: Fri Mar 30, 2018 1:02 pm
by crumb_er
Anyway, my goal would be to translate my C code in assembler code with a very simple and reduced set of instruction.
It's a university project and with our professor we decided to try to use Thumb instructions.

Re: ARM assembler Thumb instruction set

Posted: Fri Mar 30, 2018 1:04 pm
by jahboater
crumb_er wrote:
Fri Mar 30, 2018 1:02 pm
Anyway, my goal would be to translate my C code in assembler code with a very simple and reduced set of instruction.
It's a university project and with our professor we decided to try to use Thumb instructions.
OK fair enough.

Does it really really have to be a Pi Zero?

If not, just use -mthumb on your Pi3 and you are good to go!

Re: ARM assembler Thumb instruction set

Posted: Fri Mar 30, 2018 1:08 pm
by jahboater
crumb_er wrote:
Fri Mar 30, 2018 1:02 pm
my goal would be to translate my C code in assembler code with a very simple and reduced set of instruction.
Do you mean by hand?
Because that is likely the only way you will be able to use thumb on a Pi Zero.
very simple and reduced set of instruction
Do you want to do this to make it easier for you to code it?

For me, I would say the exact opposite. The more rich and powerful the instruction set available, the easier it is to write assembler code - its easy to find an instruction to do what you want. 8-bit micros were an absolute nightmare.

I'm not talking about horridly complicated things like AVX512 SIMD stuff, that definitely is hard to understand, but the day to day ARM instructions are easy.

Re: ARM assembler Thumb instruction set

Posted: Fri Mar 30, 2018 1:18 pm
by crumb_er
jahboater wrote:
Fri Mar 30, 2018 1:04 pm

Does it really really have to be a Pi Zero?
we decided to use the pi zero just because we have it but it's not obligatory to use it.

jahboater wrote:
Fri Mar 30, 2018 1:04 pm

If not, just use -mthumb on your Pi3 and you are good to go!
My question about the use of -mthumb on a pi3 is: if I use this option, is the assembly code entirely composed by Thumb instructions (16 bits) ?

Re: ARM assembler Thumb instruction set

Posted: Fri Mar 30, 2018 1:20 pm
by crumb_er
jahboater wrote:
Fri Mar 30, 2018 1:08 pm
crumb_er wrote:
Fri Mar 30, 2018 1:02 pm
my goal would be to translate my C code in assembler code with a very simple and reduced set of instruction.
Do you mean by hand?
Because that is likely the only way you will be able to do it on a Pi Zero.
Yes, by hand with the command

Code: Select all

gcc -S hello.c -mthumb

Re: ARM assembler Thumb instruction set

Posted: Fri Mar 30, 2018 1:24 pm
by jahboater
crumb_er wrote:
Fri Mar 30, 2018 1:18 pm
jahboater wrote:
Fri Mar 30, 2018 1:04 pm
If not, just use -mthumb on your Pi3 and you are good to go!
My question about the use of -mthumb on a pi3 is: if I use this option, is the assembly code entirely composed by Thumb instructions (16 bits) ?
On the Pi2 and later (that is ARMv7 or ARMv8) then it is "thumb2" which is easier to use. It is a mixture of 16 and 32-bit instructions.

You are of course free to use 16-bit instructions only if you really wanted to! (and you are doing this by hand).

The compiler (-mthumb) will use all the available instructions 32 and 64 bit.

Re: ARM assembler Thumb instruction set

Posted: Fri Mar 30, 2018 1:28 pm
by jahboater
crumb_er wrote:
Fri Mar 30, 2018 1:20 pm
Yes, by hand with the command

Code: Select all

gcc -S hello.c -mthumb
That is not by hand, that is using the compiler!!!

gcc is translating your C program.

I think you really should use a Pi3 and use -mthumb.

Re: ARM assembler Thumb instruction set

Posted: Fri Mar 30, 2018 1:30 pm
by crumb_er
jahboater wrote:
Fri Mar 30, 2018 1:28 pm
crumb_er wrote:
Fri Mar 30, 2018 1:20 pm
Yes, by hand with the command

Code: Select all

gcc -S hello.c -mthumb
That is not by hand, that is using the compiler!!!
so it's not possible to do this only with the compiler?

thanks very much for the answers ;) ;)

Re: ARM assembler Thumb instruction set

Posted: Fri Mar 30, 2018 1:35 pm
by jahboater
It is possible on a Pi3.

Code: Select all

pi@pi3:~ $ gcc hello.c -o hello
pi@pi3:~ $ size hello
   text	   data	    bss	    dec	    hex	filename
    828	    280	      4	   1112	    458	hello

pi@pi3:~ $ gcc hello.c -mthumb -o hello
pi@pi3:~ $ size hello
   text	   data	    bss	    dec	    hex	filename
    812	    280	      4	   1096	    448	hello
pi@pi3:~ $ ./hello
hello world
Only a tiny difference in size for a one line hello world program.

Re: ARM assembler Thumb instruction set

Posted: Fri Mar 30, 2018 1:57 pm
by jahboater
Here is some thumb2 code produced by the compiler on a Pi3:-
Look at the two "sub sp,sp" instructions, the compiler has chosen a 32-bit insn for the larger constant.
It really would be a pain if you were stuck with 16-bit only instructions!

Code: Select all

              .type   Disk_to_mem, %function
          Disk_to_mem:
 2DE9F047         push    {r4, r5, r6, r7, r8, r9, r10, lr}   @
 8946             mov r9, r1  @ vs_u, vs_u
          @ try.c:3478:   const int fd = in_fd ? : open( fname, O_RDONLY );
 1646             mov r6, r2  @ in_fd, in_fd
          @ try.c:3475: {
 ADF5403D         sub sp, sp, #196608 @,,
 98B0             sub sp, sp, #96 @,,
          @ try.c:3478:   const int fd = in_fd ? : open( fname, O_RDONLY );
 1AB9             cbnz    r2, .L1249  @ in_fd,
          @ try.c:3478:   const int fd = in_fd ? : open( fname, O_RDONLY );
 1146             mov r1, r2  @, in_fd
 FFF7FEFF         bl  open    @
 0646             mov r6, r0  @ in_fd,
          .L1249:
          @ try.c:3480:   if( fd < 0 )
 002E             cmp r6, #0  @ in_fd,
 07DA             bge .L1250  @,
          @ try.c:3481:     return fail(0);
 0020             movs    r0, #0  @,
          .L1281:
          @ try.c:3570:     return fail(0);
 FDF717FB         bl  fail    @
          .L1279:
          @ try.c:3573: }
 0DF5403D         add sp, sp, #196608 @,,
 18B0             add sp, sp, #96 @,,
              @ sp needed @
 BDE8F087         pop {r4, r5, r6, r7, r8, r9, r10, pc}   @
          .L1250:
          @ try.c:3483:   if( fstat( fd, &details ) != 0 )
 02A9             add r1, sp, #8  @ tmp196,,
 3046             mov r0, r6  @, in_fd
 FFF7FEFF         bl  fstat   @
 0DF16008         add r8, sp, #96 @ tmp144,,
 0246             mov r2, r0  @ _1,
 08B1             cbz r0, .L1252  @ _1,
          .L1282:
          @ try.c:3509:     return fail(fd);
 3046             mov r0, r6  @, in_fd
 EEE7             b   .L1281  @
          .L1252:
          @ try.c:3487:   if( S_ISREG(fm) )
 069C             ldr r4, [sp, #24]   @ details.st_mode, details.st_mode
 04F47044         and r4, r4, #61440  @ _2, details.st_mode,
 B4F5004F         cmp r4, #32768  @ _2,
 2CD1             bne .L1253  @,
          @ try.c:2304:   posix_fadvise( fd, 0, 0, POSIX_FADV_SEQUENTIAL );
 0146             mov r1, r0  @, tmp2
 0223             movs    r3, #2  @,
 3046             mov r0, r6  @, in_fd
 FFF7FEFF         bl  posix_fadvise   @
          .L1254:
          @ try.c:3516:   if( vs_u == in_u )
 3D4B             ldr r3, .L1283  @ tmp153,
 5B69             ldr r3, [r3, #20]   @ in_u, in_u
 4B45             cmp r3, r9  @ in_u, vs_u
 07D1             bne .L1257  @,
          @ try.c:3518:     if( S_ISREG(fm) )
 B4F5004F         cmp r4, #32768  @ _2,
 36D1             bne .L1258  @,