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

Reply via email to