From 0acb15ead6a554a6879b29fd90726b9ea8fd98c4 Mon Sep 17 00:00:00 2001 From: Duane Sand <duane.sand@imgtec.com> Date: Tue, 28 Jul 2015 14:04:29 -0700 Subject: [PATCH] [MIPS] Link .dex or .oat code lacking .MIPS.abiflags segment This corrects an issue with mips32 Art on mips64r6 Android, where Java ran slowly due to unintended use of kernel-trap emulation of single-precision floating point registers. This also regressed all Art tests due to an extra logcat line WARNING: linker: Using FRE=1 mode to run "..." When targeting mips32r6, Art generates modeless or FR=1 floating point code, same as Android's own native mips32r6 modules. So the trapping was unneeded. Linker was confusing Art-generated modules with those from old NDK compilers, which do need that trapping mode. This linker filename check may become unnecessary, if Art learns how to generate .MIPS.abiflags segments in its generated elf-like codefiles. Change-Id: I18069d1234960c680c5df739514da09015a7fdb6 --- linker/linker_mips.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/linker/linker_mips.cpp b/linker/linker_mips.cpp index 75ea29042..4dc97c8bd 100644 --- a/linker/linker_mips.cpp +++ b/linker/linker_mips.cpp @@ -264,10 +264,18 @@ bool soinfo::mips_check_and_adjust_fp_modes() { // FP ABI-variant compatibility checks for MIPS o32 ABI if (abiflags == nullptr) { - // Old compiles lack the new abiflags section. - // These compilers used -mfp32 -mdouble-float -modd-spreg defaults, - // ie FP32 aka DOUBLE, using odd-numbered single-prec regs - mips_fpabi = MIPS_ABI_FP_DOUBLE; + // Old compilers and some translators don't emit the new abiflags section. + const char* filename = get_realpath(); + size_t len = strlen(filename); + if (len > 4 && (strcmp(filename+len-4, ".dex") == 0 || + strcmp(filename+len-4, ".oat") == 0 )) { + // Assume dex2oat is compatible with target + mips_fpabi = MIPS_ABI_FP_XX; + } else { + // Old Android compilers used -mfp32 -mdouble-float -modd-spreg defaults, + // ie FP32 aka DOUBLE, using FR=0 mode fpregs & odd single-prec fpregs + mips_fpabi = MIPS_ABI_FP_DOUBLE; + } } else { mips_fpabi = abiflags->fp_abi; if ( (abiflags->flags1 & MIPS_AFL_FLAGS1_ODDSPREG)