http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60123

            Bug ID: 60123
           Summary: TIC6x: EABI incompatibility when large struct is
                    returned from function and is not used by the caller
           Product: gcc
           Version: 4.9.0
            Status: UNCONFIRMED
          Severity: major
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: wojtek.golf at interia dot pl

=================================================================================
Exact version of gcc:
tic6x-none-elf-gcc (GCC) 4.9.0 20140208 (experimental)

================================================================================
System type:
Linux wmigda-desktop 3.11.0-13-generic #20-Ubuntu SMP Wed Oct 23 17:26:33 UTC
2013 i686 i686 i686 GNU/Linux

================================================================================
Options given when gcc was built:

export TRIPLET=tic6x-none-elf
mkdir -pv ${X_BUILD_DIR}/gcc-${GCC_VER}-build-pass-1/

pushd ${X_BUILD_DIR}gcc-${GCC_VER}-build-pass-1/ && \
RANLIB_FOR_TARGET=${CXTOOLS}bin/${TRIPLET}-ranlib
AS_FOR_TARGET=${CXTOOLS}bin/${TRIPLET}-as
AR_FOR_TARGET=${CXTOOLS}bin/${TRIPLET}-ar \
AS=as AR=ar LDFLAGS='-lstdc++ -lm' ../../../../gcc/configure \
--prefix=${C_TOOLS} \
--build=$(gcc -dumpmachine) \
--host=$(gcc -dumpmachine) \
--target=${TRIPLET} \
--with-local-prefix=${CXTOOLS}${TRIPLET}/sysroot \
--with-sysroot=${CXTOOLS}${TRIPLET}/sysroot \
--disable-nls \
--disable-shared \
--without-headers \
--with-newlib \
--disable-decimal-float \
--disable-libgomp \
--disable-libmudflap \
--disable-libssp \
--disable-libatomic \
--disable-libquadmath \
--disable-threads \
--enable-languages=c \
--disable-multilib \
--with-mpfr=${C_TOOLS} \
--with-gmp=${C_TOOLS} \
--disable-__cxa_atexit \
--disable-sjlj-exceptions \
--enable-target-optspace \
--disable-libstdcxx-pch \
; popd

================================================================================
Commandline:
tic6x-none-elf-gcc -fleading-underscore -march=c674x -O2 -g0 -S main.c

================================================================================
Compiler output:
nothing one the console

================================================================================
Preprocessed file:

# 1 "main.c"
# 1 "<command-line>"
# 1 "main.c"
typedef struct A
{
    long long y;
    char z;
} struct_A;

extern struct_A e_struct1;

struct_A g_fun_6(void)
{
    return e_struct1;
}

================================================================================
The problem:
SPRAB89 document from Texas Instruments states that:
"If the called function returns a structure or union larger than 64 bits, the
caller must pass an additional argument in A3 containing a destination address
for the returned value, or 0 if the returned value is not used. The callee
returns the object by copying it to the address in A3, if non-zero."

Assembler listing generated by gcc doesn't check for the passed address being
non-NULL:

_g_fun_6:
        mvkl    .s1 (_e_struct1), A5
    ||  mv  .d1 A3, A4
        mvkh    .s1 (_e_struct1), A5
        lddw    .d1t1   *A5, A7:A6
        lddw    .d1t1   *+A5(8), A9:A8
    ||  ret .s2 B3
        nop 3
        stdw    .d1t1   A7:A6, *A3
        stdw    .d1t1   A9:A8, *+A3(8)

whereas assembler generated by TI CGTools' cl6x compiler does. Hence, if the
code compiled with cl6x calls code produced by gcc a NULL pointer write will
occur.
Also, in the assembler above copying A3 to A4 (mv  .d1 A3, A4) doesn't relate
to anything and could be eliminated altogether.

Reply via email to