This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
gcc-3.4.0 fails for ColdFire(does not satisfy constraints)
- From: Peter Barada <peter at the-baradas dot com>
- To: gcc at gcc dot gnu dot org
- Date: Mon, 26 Apr 2004 12:24:14 -0400 (EDT)
- Subject: gcc-3.4.0 fails for ColdFire(does not satisfy constraints)
I'm trying to use gcc-3.4.0 --target=m68k-uclinux, and it fails while
trhing to build printf.c from uClibc:
m68k-uclinux-gcc -Wall -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -Os -Wa,--bitwise-or -I/home/peter/work/src/ucLinux/ucTools/linux-2.4.x/include -m5200 -msoft-float -fno-builtin -nostdinc -D_LIBC -I../../include -I. -I/home/mylocal/uclinux/tools-3.4.0/lib/gcc/m68k-uclinux/3.4.0/include -DNDEBUG -DL__fpmaxtostr printf.c -c -o _fpmaxtostr.o
printf.c: In function `_fpmaxtostr':
printf.c:2454: error: insn does not satisfy its constraints:
(insn 1376 536 537 38 (set (reg:QI 8 %a0)
(mem:QI (plus:SI (reg/f:SI 14 %a6)
(const_int -209 [0xffffff2f])) [0 mode+0 S1 A8])) 33 {*m68k.md:826} (nil)
(nil))
printf.c:2454: internal compiler error: in reload_cse_simplify_operands, at postreload.c:378
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.
make[2]: *** [_fpmaxtostr.o] Error 1
make[2]: Leaving directory `/home/peter/work/src/ucLinux/ucTools/uClibc-0.9.26/libc/stdio'
This problem has been reported before, so I decided to try to fix it
by preventing bytes from being stored in address registers by modifying the
movqi pattern for ColdFire from :
(define_insn ""
[(set (match_operand:QI 0 "nonimmediate_operand" "=d<Q>,dm,U,d*a")
(match_operand:QI 1 "general_src_operand" "dmi,d<Q>,U,di*a"))]
"TARGET_COLDFIRE"
"* return output_move_qimode (operands);")
to:
(define_insn ""
[(set (match_operand:QI 0 "nonimmediate_operand" "=d<Q>,dm,U,d")
(match_operand:QI 1 "general_src_operand" "dmi,d<Q>,U,di"))]
"TARGET_COLDFIRE"
"* return output_move_qimode (operands);")
As well as modify HARD_REGNO_MODE_OK from:
#define HARD_REGNO_MODE_OK(REGNO, MODE) \
(((REGNO) < 16 \
&& !((REGNO) < 8 && (REGNO) + GET_MODE_SIZE (MODE) / 4 > 8)) \
|| ((REGNO) >= 16 && (REGNO) < 24 \
&& (GET_MODE_CLASS (MODE) == MODE_FLOAT \
|| GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT) \
&& GET_MODE_UNIT_SIZE (MODE) <= 12))
To:
#define HARD_REGNO_MODE_OK(REGNO, MODE) \
regno_mode_ok(REGNO, MODE)
along with the following code:
/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
On the 68000, the cpu registers can hold any mode except bytes in
address registers, but the 68881 registers
can hold only SFmode or DFmode. */
int regno_mode_ok(int regno, enum machine_mode mode)
{
if (regno < 8)
{
/* Data Registers */
return 1;
}
else if (regno < 16)
{
/* Address Registers, can't hold bytes, can hold aggregate if
fits in */
if (GET_MODE_SIZE (mode) == 1)
return 0;
if (!((regno) < 8 && (regno) + GET_MODE_SIZE (mode) / 4 > 8))
return 1;
}
else if (regno < 24)
{
/* FPU registers, hold float or complex float of long double or smaller */
if ((GET_MODE_CLASS (mode) == MODE_FLOAT
|| GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
&& GET_MODE_UNIT_SIZE (mode) <= 12)
return 0;
}
return 0;
}
Now fails with:
printf.c: In function `_fpmaxtostr':
printf.c:2454: error: unable to find a register to spill in class `ADDR_REGS'
printf.c:2454: error: this is the insn:
(insn 537 536 538 38 (set (subreg:SI (reg/v:QI 50 [ mode ]) 0)
(plus:SI (subreg:SI (reg/v:QI 50 [ mode ]) 0)
(const_int 32 [0x20]))) 90 {*addsi3_5200} (nil)
(nil))
Breakpoint 1, fancy_abort (
file=0x82582e0 "/home/peter/work/src/ucLinux/ucTools/gcc-3.4.0/gcc/reload1.c",
line=1874, function=0x82580f7 "spill_failure")
at /home/peter/work/src/ucLinux/ucTools/gcc-3.4.0/gcc/diagnostic.c:584
Any suggestions where I go from here are most appreciated.
--
Peter Barada
peter@the-baradas.com