arm-none-eabi-gcc generates redundant assembler lines.

Asked by Dawid Babula

Hello,

I'd like to ask you why arm-none-eabi-gcc is emitting in my opinion redundant assembler for the following c code. Here is also my configuration :

arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors) 4.9.3 20150529 (release) [ARM/embedded-4_9-branch revision 227977]
GNU objdump (GNU Tools for ARM Embedded Processors) 2.24.0.20150921
Ubuntu 14.04.3 LTS

CFLAGS = -c
CFLAGS += -pipe
CFLAGS += -march=armv7-m -mtune=cortex-m3 -mcpu=cortex-m3 -mthumb
CFLAGS += -gdwarf-2
CFLAGS += -std=c99
CFLAGS += -O2
CFLAGS += -Wall
CFLAGS += -Wextra
CFLAGS += -Wpedantic
CFLAGS += -Wbad-function-cast
CFLAGS += -Wcast-align
CFLAGS += -Wdeclaration-after-statement
CFLAGS += -Wfloat-equal
CFLAGS += -Wdouble-promotion
CFLAGS += -Wmissing-declarations
CFLAGS += -Wmissing-prototypes
CFLAGS += -Wnested-externs
CFLAGS += -Wold-style-definition
CFLAGS += -Wredundant-decls
CFLAGS += -Wshadow
CFLAGS += -Wstrict-prototypes
CFLAGS += -Wuninitialized
CFLAGS += -Winit-self
CFLAGS += -Wmissing-include-dirs
CFLAGS += -Wsync-nand
CFLAGS += -Wundef
CFLAGS += -Wcast-qual
CFLAGS += -Wjump-misses-init
CFLAGS += -Wlogical-op
CFLAGS += -Wpacked
CFLAGS += -Winline
CFLAGS += -Wjump-misses-init
CFLAGS += -Wlarger-than=1024
CFLAGS += -Wframe-larger-than=128
CFLAGS += -Wstack-usage=384
CFLAGS += -Wswitch-enum
CFLAGS += -Wswitch-default
CFLAGS += -Waggregate-return
#CFLAGS += -Wconversion
#CFLAGS += -Wpadded
CFLAGS += -fno-strict-aliasing
CFLAGS += -fshort-enums
CFLAGS += -ffunction-sections
CFLAGS += -fdata-sections
CFLAGS += -fno-common

template_driver.c

#include "template_driver.h"

static inline uint32_t hello(uint32_t last,uint32_t x,uint32_t y)
{
    for(uint32_t i=last;i!=0;i--)
    {
        x+= (y*x);
    }

    return (x-y);
}

int32_t TEMPLATE_DRIVER_configure(uint32_t timeout)
{
    if(hello(timeout,3,10) != 0)
    {
        return -1;
    }
    else
    {
        return 0;
    }
}

template_driver. h

#ifndef TEMPLATE_DRIVER_H
#define TEMPLATE_DRIVER_H

#include <stdint.h>

int32_t TEMPLATE_DRIVER_configure(uint32_t timeout);

#endif

I'm disassembling the object file with following command:

arm-none-eabi-objdump -d -marm -M reg-names-std -M force-thumb template_driver.o > out.lst 2>&1

and this is what I'm getting

out.lst:

template_driver.o: file format elf32-littlearm

Disassembly of section .text.TEMPLATE_DRIVER_configure:

00000000 <TEMPLATE_DRIVER_configure>:
   0: b160 cbz r0, 1c <TEMPLATE_DRIVER_configure+0x1c>
   2: 2303 movs r3, #3
   4: eb03 0283 add.w r2, r3, r3, lsl #2
   8: 3801 subs r0, #1
   a: eb03 0342 add.w r3, r3, r2, lsl #1
   e: d1f9 bne.n 4 <TEMPLATE_DRIVER_configure+0x4>
  10: f1b3 000a subs.w r0, r3, #10
  14: bf18 it ne
  16: f04f 30ff movne.w r0, #4294967295
  1a: 4770 bx lr
  1c: f04f 30ff mov.w r0, #4294967295
  20: 4770 bx lr
  22: bf00 nop

aren't assembler lines from 1c to 22 redundant in this case? Why I'm seeing quite often a nop instruction at the end of functions ?

Question information

Language:
English Edit question
Status:
Solved
For:
GNU Arm Embedded Toolchain Edit question
Assignee:
No assignee Edit question
Solved by:
Joey Ye
Solved:
Last query:
Last reply:
Revision history for this message
Best Joey Ye (jinyun-ye) said :
#1

Dawid,

1c to 22 is not redundant, as you can see the instruction at 0 jumps to 1c. It might not the the most code size optimal though in -O2.

As to the nop at the end, it is to make sure the following function will start at 4 byte aligned boundary, which is a normal trick for alignment.

Hope it explains everything.

Thanks,
Joey

Revision history for this message
Dawid Babula (dbabula) said :
#2

Hi,

Thank you I get it now. I didn't notice jump at the beginning.

Revision history for this message
Dawid Babula (dbabula) said :
#3

Thanks Joey Ye, that solved my question.