This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Automatic MMX/x87 FPU mode switching - erratum


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.



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]