11
votes

I'm inspecting the assembly language output of a C program I'm compiling for the ARM Android platform using GCC (the version included in the Android NDK).

I'm specifying the ARM instruction set which are 4 bytes in length rather than THUMB, but surprisingly, the emmited assembly language code is aligning functions to a 2 byte boundary!

Here is a sample of the generated code showing the wrong .align directive:

.Ltext0:
    .global __aeabi_dmul
    .global __aeabi_d2iz
    .section    .text.InitializeFIRFilter,"ax",%progbits
    .align  2
    .global InitializeFIRFilter
    .type   InitializeFIRFilter, %function
InitializeFIRFilter:
    .fnstart

According to this document, the correct alignment should be 4 which makes sense.

I'm trying to force the alignment by using the -falign-functions=4 but it is being ignored.

Here are the build flags I'm specifying in the Android.mk file

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
    LOCAL_ARM_MODE  := arm
    LOCAL_MODULE    := nativeJadeMobile
    LOCAL_SRC_FILES := nativeJadeMobile.c fftasm.s
    LOCAL_LDLIBS    := -llog
    LOCAL_CFLAGS += -marm -ffast-math -O2 -march=armv6 -falign-functions=4 -save-temps -S 
    include $(BUILD_SHARED_LIBRARY)

Can anybody spot what am I doing wrong, or know how can I enforce the correct code alignment? Thank you very much in advance!

1
For the record, the default mode of GCC on NDK is emitting a mix of ARM and Thumb code. Thumb instructions are aligned on 16-bit boundaries.Seva Alekseyev
Hopefully modern GCC will always use .p2align which is unambiguously a power of 2, rather than target-dependent whether it's a byte count or exponent.Peter Cordes

1 Answers

16
votes

According to the assembler's documentation, the .align pseudo op specifies a power of two for the ARM architecture. Therefore, the alignment is 2^2=4 bytes, which is correct.