Cortex-m4 asm vs cortex-m0 asm

0

How would one rewrite this assembly code for CM4 to CM0? This is example of hardfault handling from FreeRTOS page. It checks which stack pointer was active before hardfault occurred and gives pointer to the beginning of stacked registers:

" tst lr, #4                                                \n"
" ite eq                                                    \n"
" mrseq r0, msp                                             \n"
" mrsne r0, psp                                             \n"
" ldr r1, [r0, #24]                                         \n"
" ldr r2, handler2_address_const                            \n"
" bx r2                                                     \n"
" handler2_address_const: .word prvGetRegistersFromStack    \n"

Without any changes it produces multiple errors:

 Error: unshifted register required -- tst r0,#4''
 Error: selected processor does not support 'ite eq' in Thumb mode
 Error: Thumb does not support conditional execution
 Error: Thumb does not support conditional execution
 Error: invalid offset, target not word aligned (0x00000002)
 Error: invalid offset, value too big (0x00000002)

What I have tried:

Replace tst and remove IT this way

" mov r1, lr\n"
" lsr r0, r1, #3\n"    // Replace tst with lsr and cmp
" cmp r0, #1\n"
" mrseq r0, msp\n"     // <- Error: Thumb does not support conditional execution
" mrsne r0, psp\n"     // <- Error: Thumb does not support conditional execution

Ok. Enable something called unified syntax:

".syntax unified\n"
".thumb\n"
" mov r1, lr\n"
" lsrs r0, r1, #3\n"  // tst gives "Can not honor suffix width" so replaced it with lsrs and cmp
" cmp r0, #1\n"
" ite eq\n"          // <- Error: selected processor does not support `ite eq' in Thumb mode. If I remove it compiler states that mrseq must be in IT block
" mrseq r0, msp\n"
" mrsne r0, psp\n"
" ldr r1, [r0, #24]\n"
" ldr r2, handler2_address_const\n"
" bx r2\n"
" handler2_address_const: .word prvGetRegistersFromStack\n"

What are the reasons for those errors and how to fix them? Still got no idea what causes alignment problem.

Certainly some instruction are not supported on CM0. But I don't understand error "Thumb does not support conditional execution" and how to live without conditional execution.

Also what does error "Can not honor register width" means and why it occurs when unified syntax is enabled. As I understand it is something about 16/32 bit instructions. Tried to add .W suffix but got another error.

assembly
arm
cortex-m
asked on Stack Overflow Nov 27, 2019 by Long Smith • edited Nov 27, 2019 by Long Smith

1 Answer

0

Cortex-M0 apparently doesn't support predication at all; no conditional execution. The obvious option would be to branch.

Your lsrs sequence doesn't look like it correctly implements testing the right bit, or testing a single bit. Looks like it depends on all higher bits being zero.

GCC output https://godbolt.org/z/aphU5G shows a clever way to branch on a single bit with one shift instruction: lsls r3, r0, #29 ; bpl .skip - shifts the bit to the sign bit where a flag is set based on just that bit. The r3 destination can be any dummy register that's encodeable; you don't care about the value; you just want the flag setting.

answered on Stack Overflow Nov 27, 2019 by Peter Cordes

User contributions licensed under CC BY-SA 3.0