On Wed, Jul 19, 2006 at 07:52:32AM +0200, Wolfgang Mües wrote: > Hello, > > after getting a "working" version of the gcc 4.0.2 with the Nintendo > 8-bit-write problem, I was busy the last weeks trying to adapt the > linux system (replacing I/O with writeb() macros, removing strb > assembler calls).
It is good to hear from you again. > However, it turned out that the sources of the linux kernel are a far > more demanding test than every single small test case. Such is life. Since the ARM backend has many arm_expand_fubar() functions, it wouldn't too surpricing if one of them would now generate invalid insns. > I have tried my very best to implement the last patch from Rask (thank > you very much!). There was one place I was not shure I have coded the > right solution: > > + (match_code "reg" "0"))) > > My patch (without the second operand for match_code): > > > (match_test "GET_CODE (XEXP (op, 0)) == REG"))) > > Is this the right substitution? I believe it is. > If I compile the linux kernel with this patch, many files get compiled > without problems, but in fs/vfat/namei.c I get: > > > fs/vfat/namei.c: In function 'vfat_add_entry': > > fs/vfat/namei.c:694: error: unrecognizable insn: > > (insn 2339 2338 2340 188 (set (mem/s/j:QI (reg:SI 14 lr) [0 > > <variable>.attr+0 S1 A8]) (reg:QI 12 ip)) -1 (nil) > > (nil)) > > fs/vfat/namei.c:694: internal compiler error: in extract_insn, at > > recog.c:2020 Please submit a full bug report, > > I can't see what is going on here... The (clobber ...) part is missing. The first thing to do is to compile with -fdump-rtl-all and see which pass creates this invalid insn. Grep is your friend. I've spotted a function named emit_set_insn() in arm.c. It might be the problem, because it uses gen_rtx_SET() directly. Thus, if Y is a general operand, the resulting insn should match one of the move patterns, but the (clobber ...) expression needed for "_arm_movqi_insn_swp" will be missing. For example, arm_split_constant() contains these potentially problematic lines: emit_set_insn (target, GEN_INT (val)); rtx temp = subtargets ? gen_reg_rtx (mode) : target; emit_set_insn (temp, GEN_INT (val)); There are other functions which call emit_set_insn(). I have no idea which one, if any, of these calls is causing the problem. It could also be one of the RTL passes. The function named emit_move_insn() ought to do the trick here, but is perhaps a bit heavyweight for this purpose. Anyway, try this patch (untested), which should plug this particular hole: Index: gcc/config/arm/arm.c =================================================================== --- gcc/config/arm/arm.c (revision 115021) +++ gcc/config/arm/arm.c (working copy) @@ -709,12 +709,15 @@ TLS_LE32 }; -/* Emit an insn that's a simple single-set. Both the operands must be known - to be valid. */ +/* Emit an insn that's a simple single-set if Y isn't a general operand. + Both the operands must be known to be valid. */ inline static rtx emit_set_insn (rtx x, rtx y) { - return emit_insn (gen_rtx_SET (VOIDmode, x, y)); + if (general_operand (y, GET_MODE (x)) + return emit_move_insn (x, y); + else + return emit_insn (gen_rtx_SET (VOIDmode, x, y)); } /* Return the number of bits set in VALUE. */ -- Rask Ingemann Lambertsen