Created attachment 23472 [details] Small testcase. I get the following error when using gcc to cross compile to an SH4 target. # /opt/sh4/bin/sh4-linux-gcc -c -O1 sh4-gcc.c sh4-gcc.c: In function 'xml_transport_parser': sh4-gcc.c:104: error: unable to find a register to spill in class 'FPUL_REGS' sh4-gcc.c:104: error: this is the insn: (insn 199 198 200 18 sh4-gcc.c:76 (set (mem/s/j:QI (plus:SI (reg:SI 77 fr13 [320]) (reg:SI 76 fr12 [orig:240 D.2212 ] [240])) [0 name S1 A8]) (reg:QI 1 r1 [284])) 182 {movqi_i} (expr_list:REG_DEAD (reg:QI 1 r1 [284]) (expr_list:REG_DEAD (reg:SI 76 fr12 [orig:240 D.2212 ] [240]) (nil)))) sh4-gcc.c:104: confused by earlier errors, bailing out The problem only seems to happen with -O1. Here is the information about my compiler: #sh4-linux-gcc -v Using built-in specs. Target: sh4-linux Configured with: /usr/src/BUILD/gcc/configure --prefix=/opt/sh4 --target=sh4-linux --with-cpu=sh4a --with-multilib-list=sh4a,sh4a-nofpu --enable-incomplete-targets --disable-nls --disable-libssp --disable-libgomp --disable-libmudflap --enable-shared --enable-languages=c,c++ --enable-cross --enable-__cxa_atexit --enable-threads=posix --with-sysroot=/opt/sh4/crossroot Thread model: posix gcc version 4.3.4 [gcc-4_3-branch revision 152973] (GCC) Attached is a small test case.
Created attachment 23473 [details] Preprocessor output for testcase Attaching preprocessor output.
It looks a reload problem for this target. 4.3 compiler tries to reload an insn like (set (mem/s/j:QI (plus:SI (reg:SI 77 fr13 [216]) (reg:SI 76 fr12 [orig:166 D.1219 ] [166])) [0 name S1 A8]) (reg:QI 218)) and finds that fr12 and fr13 are required to reload to non-fp registers via fpul register. The register allocater of 4.3 doesn't like to use fupl twice in a memory address to reload and fails at the above insn. I'm afraid that there is no easy generic way to avoid it without modifying register allocater of 4.3 which is now very stable for other targets. We have new IRA register allocater for 4.4 and after which don't fail against that case. An easy work around on target side is not to use fp-regs for SImode when the target allows the reg+reg addressing mode, though it might make the code slightly worse in some situations. --- ORIG/gcc-4_3-branch/gcc/config/sh/sh.h 2008-07-21 08:38:08.000000000 +0900 +++ LOCAL/gcc-4_3-branch/gcc/config/sh/sh.h 2011-03-02 12:43:10.000000000 +0900 @@ -1237,7 +1237,7 @@ extern char sh_additional_register_names ? (FP_REGISTER_P (REGNO) && ((REGNO) - FIRST_FP_REG) % 16 == 0) \ : (REGNO) == FIRST_XD_REG) \ : FP_REGISTER_P (REGNO) \ - ? ((MODE) == SFmode || (MODE) == SImode \ + ? ((MODE) == SFmode || ((MODE) == SImode && !ALLOW_INDEXED_ADDRESS) \ || ((TARGET_SH2E || TARGET_SHMEDIA) && (MODE) == SCmode) \ || ((((TARGET_SH4 || TARGET_SH2A_DOUBLE) && (MODE) == DFmode) || (MODE) == DCmode \ || (TARGET_SHMEDIA && ((MODE) == DFmode || (MODE) == DImode \
Fixed for 4.4.5.