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.