From: Peter Barada To: gcc-patches@gcc.gnu.org Subject: Re: gcc-3.4.0 fails for ColdFire(does not satisfy constraints) Date: Tue, 4 May 2004 12:47:52 -0400 (EDT) I'm trying to use gcc-3.4.0 --target=m68k-uclinux, and it fails while building 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 for instructions. make[2]: *** [_fpmaxtostr.o] Error 1 make[2]: Leaving directory `/home/peter/work/src/ucLinux/ucTools/uClibc-0.9.26/libc/stdio' To fix this I: 1) Modify m68k.h/m68k.c to disallow bytes in address registers 2) Change addsi_5200 to add 'i' constraint 3) Add define_peephole2 to convert add.l #9,%d0 into moveq.l #9,%Dx; add.l %Dx,%Dy when a data register is available. Built and tested uClinux on ColdFire platform. gcc/ 2004-04-23 Peter Barada * config/m68k/m68k.h: disallow bytes in address registers. * config/m68k/m68k.c: Likewise. * config/m68k/m68k.md: add 'i' to addsi3_5200, add peephole2 to use a data register to hold the constant for the add if one is available. Index: m68k-protos.h =================================================================== RCS file: /cvs/uberbaum/gcc/config/m68k/m68k-protos.h,v retrieving revision 1.14 diff -c -3 -p -r1.14 m68k-protos.h *** gcc-3.4/gcc/config/m68k/m68k-protos.h 11 Oct 2003 06:35:53 -0000 1.14 --- gcc-3.4/gcc/config/m68k/m68k-protos.h 4 May 2004 16:39:56 -0000 *************** *** 1,5 **** /* Definitions of target machine for GNU compiler. Sun 68000/68020 version. ! Copyright (C) 2000, 2002 Free Software Foundation, Inc. This file is part of GCC. --- 1,5 ---- /* Definitions of target machine for GNU compiler. Sun 68000/68020 version. ! Copyright (C) 2000, 2002, 2004 Free Software Foundation, Inc. This file is part of GCC. *************** extern int const_sint32_operand (rtx, en *** 45,50 **** --- 45,51 ---- extern int floating_exact_log2 (rtx); extern int not_sp_operand (rtx, enum machine_mode); extern int valid_dbcc_comparison_p (rtx, enum machine_mode); + extern int valid_mov3q_const(rtx); extern int extend_operator (rtx, enum machine_mode); extern bool strict_low_part_peephole_ok (enum machine_mode mode, rtx first_insn, rtx target); *************** extern void notice_update_cc (rtx, rtx); *** 57,66 **** --- 58,69 ---- extern int general_src_operand (rtx, enum machine_mode); extern int nonimmediate_src_operand (rtx, enum machine_mode); extern int memory_src_operand (rtx, enum machine_mode); + extern int register_or_memory_operand (rtx, enum machine_mode); extern int pcrel_address (rtx, enum machine_mode); extern rtx legitimize_pic_address (rtx, enum machine_mode, rtx); #endif /* RTX_CODE */ + extern int m68k_regno_mode_ok(int, enum machine_mode); extern int flags_in_68881 (void); extern bool use_return_insn (void); extern void override_options (void); Index: m68k.c =================================================================== RCS file: /cvs/uberbaum/gcc/config/m68k/m68k.c,v retrieving revision 1.129 diff -c -3 -p -r1.129 m68k.c *** gcc-3.4/gcc/config/m68k/m68k.c 10 Mar 2004 05:07:45 -0000 1.129 --- gcc-3.4/gcc/config/m68k/m68k.c 4 May 2004 16:39:56 -0000 *************** pcrel_address (rtx op, enum machine_mode *** 3222,3227 **** --- 3222,3235 ---- || GET_CODE (op) == CONST); } + /* Predicate to allow either memory or register operand. Used by + peepholes. */ + int + register_or_memory_operand (rtx op, enum machine_mode mode) + { + return (register_operand(op, mode) || memory_operand(op, mode)); + } + const char * output_andsi3 (rtx *operands) { *************** m68k_struct_value_rtx (tree fntype ATTRI *** 3423,3426 **** --- 3431,3466 ---- } output_asm_insn (fmt, xops); } + + /* 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 + m68k_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 1; + } + return 0; + } Index: m68k.h =================================================================== RCS file: /cvs/uberbaum/gcc/config/m68k/m68k.h,v retrieving revision 1.110 diff -c -3 -p -r1.110 m68k.h *** gcc-3.4/gcc/config/m68k/m68k.h 10 Mar 2004 05:07:45 -0000 1.110 --- gcc-3.4/gcc/config/m68k/m68k.h 4 May 2004 16:39:57 -0000 *************** extern int target_flags; *** 548,563 **** : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) /* 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 but the 68881 registers ! can hold only SFmode or DFmode. */ #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)) /* Value is 1 if it is a good idea to tie two pseudo registers --- 548,558 ---- : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) /* 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, the 68881 registers can hold only SFmode or DFmode. */ #define HARD_REGNO_MODE_OK(REGNO, MODE) \ ! m68k_regno_mode_ok ((REGNO), (MODE)) /* Value is 1 if it is a good idea to tie two pseudo registers Index: m68k.md =================================================================== RCS file: /cvs/uberbaum/gcc/config/m68k/m68k.md,v retrieving revision 1.75 diff -c -3 -p -r1.75 m68k.md *** gcc-3.4/gcc/config/m68k/m68k.md 16 Mar 2004 03:54:33 -0000 1.75 --- gcc-3.4/gcc/config/m68k/m68k.md 4 May 2004 16:39:58 -0000 *************** *** 1884,1892 **** (define_insn "*addsi3_5200" [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?a,?a,r") (plus:SI (match_operand:SI 1 "general_operand" "%0,a,rJK,0") ! (match_operand:SI 2 "general_src_operand" "d,rJK,a,mrIKLs")))] "TARGET_COLDFIRE" "* return output_addsi3 (operands);") (define_insn "" [(set (match_operand:SI 0 "nonimmediate_operand" "=a") --- 1884,1905 ---- (define_insn "*addsi3_5200" [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?a,?a,r") (plus:SI (match_operand:SI 1 "general_operand" "%0,a,rJK,0") ! (match_operand:SI 2 "general_src_operand" "d,rJK,a,mrIKLi")))] "TARGET_COLDFIRE" "* return output_addsi3 (operands);") + + + ; Peephole to convert 'add.l #9,%d0' into 'moveq.l #9,%d1;add.l %d1,%d0' + ; if there's a spare data register around. + (define_peephole2 + [(match_scratch:SI 2 "d") + (set (match_operand:SI 0 "register_or_memory_operand" "rm") + (plus:SI (match_dup 0) + (match_operand:SI 1 "immediate_operand" "J")))] + "/* optimize_size && */ INTVAL (operands[1]) >= -0x80 && INTVAL (operands[1]) < 0x80" + [(set (match_dup 2) (match_dup 1)) + (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))] + "") (define_insn "" [(set (match_operand:SI 0 "nonimmediate_operand" "=a")