This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Automatic MMX/x87 FPU mode switching - erratum
- From: Uros Bizjak <uros dot bizjak at kss-loka dot si>
- To: Richard Henderson <rth at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Fri, 01 Jul 2005 14:05:57 +0200
- Subject: Re: Automatic MMX/x87 FPU mode switching - erratum
- References: <1119350611.42b7ef5373f49@ssl.kss-loka.si> <20050627052044.GD27305@redhat.com> <1119947886.42c10c6e7f6f2@ssl.kss-loka.si> <20050628164510.GA17378@redhat.com> <1120209233.42c50951ae0eb@ssl.kss-loka.si>
Hello Richard!
> /* Emit use pattern and attach register usage
> to call_insn pattern. */
> if (regno)
> {
> rtx reg = gen_rtx_REG (ALLREGSmode, regno);
> rtx use = gen_rtx_USE (VOIDmode, reg);
> rtx call_fusage = 0;
>
> use_reg (&call_fusage, reg);
> add_function_usage_to (insn, call_fusage);
>
> emit_insn_before (use, insn);
> }
Uh, emitting use insn is certainly wrong. However, without use isns, an
"internal consistency failure" in verify_wide_reg () will be triggered, despite
the fact that registers are live at start of bb.
If this check is removed, life data is still correct, so I wonder, what is the
purpose of this check (and how to avoid it ...:)
Uros.
>
> if (mmx)
> return FPU_MODE_MMX;
>
> if (x87)
> return FPU_MODE_X87;
>
> return FPU_MODE_DEFAULT;
> }
>
> --cut here--
>
> With these changes applied, the testcase from my previous post now
> produces
> correct register life information:
>
> ;; Start of basic block 0, registers live: 6 [bp] 7 [sp] 20 [frame] 29 [mm0]
> 30
> [mm1] 31 [mm2] 32 [mm3] 33
> [mm4] 34 [mm5] 35 [mm6] 36 [mm7]
> (note:HI 10 7 47 0 [bb 0] NOTE_INSN_BASIC_BLOCK)
>
> ...
>
> (insn 41 50 12 0 (set (reg:ALLREGS 8 st)
> (unspec_volatile:ALLREGS [
> (reg:ALLREGS 29 mm0)
> ] 2)) 871 {efpu} (nil)
> (expr_list:REG_DEAD (reg:ALLREGS 29 mm0)
> (nil)))
>
> ...
>
> (insn 39 13 14 0 (use (reg:ALLREGS 8 st)) -1 (nil)
> (nil))
>
> (call_insn:HI 14 39 15 0 (set (reg:V8QI 29 mm0)
> (call (mem:QI (symbol_ref:SI ("aaa") [flags 0x41] <function_decl
> 0x40305360 aaa>) [0 S1 A8])
> (const_int 0 [0x0]))) 526 {*call_value_0} (insn_list:REG_DEP_TRUE
> 12
> (insn_list:REG_DEP_TRUE 1
> 3 (nil)))
> (expr_list:REG_DEAD (reg:ALLREGS 8 st)
> (expr_list:REG_DEAD (reg:V8QI 30 mm1)
> (nil)))
> (expr_list:REG_DEP_TRUE (use (reg:V8QI 29 mm0))
> (expr_list:REG_DEP_TRUE (use (reg:V8QI 30 mm1))
> (expr_list:REG_DEP_TRUE (use (reg:ALLREGS 8 st))
> (nil)))))
>
> ...
>
> (insn 40 21 36 0 (set (reg:ALLREGS 29 mm0)
> (unspec_volatile:ALLREGS [
> (reg:ALLREGS 8 st)
> ] 5)) 872 {emms} (nil)
> (expr_list:REG_DEAD (reg:ALLREGS 8 st)
> (nil)))
>
> ...
>
> ;; End of basic block 0, registers live:
> 0 [ax] 6 [bp] 7 [sp] 20 [frame] 29 [mm0] 30 [mm1] 31 [mm2] 32 [mm3] 33 [mm4]
> 34
> [mm5] 35 [mm6] 36 [mm7]
>
> If everything works OK, then efpu/emms/call patterns (that can change FPU
> mode) should be marked with an expression:
>
> (expr_list:REG_DEAD (reg:ALLREGS 8 st)
>
> Which in fact "enables" registers of the opposite unit.
>
> As far as I have tested, this approach handles register life information
> correctly through various combinations of call instructions, branches, etc.
>
> I would be very grateful for your opinion on these changes, before I move to
> reg-stack.c hacking (reg-stack.c needs some hacking in function entry and
> exit
> compensation code, because it doesn't expect live FP registers on function
> boundaries.)
>
> Uh, and http://gcc.gnu.org/wiki/reload was avoided this way :)
>
> Uros.