This is the mail archive of the 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]

Re: dangerous cleverness? ppc int<->float conversions, subreg

On Wed, Oct 24, 2001 at 02:35:35PM -0700, Richard Henderson wrote:
> Does the branch include the mode argument to REGISTER_MOVE_COST?
> If so, I suspect that you'll get the proper effect from making
> the cost of an integer mode in an fp reg equal to MEMORY_MOVE_COST
> of the same register.  This ought to prevent an fp register from
> being preferred, while not actively disallowing it.

The branch has two-argument REGISTER_MOVE_COST.

However, I tried doing as you suggested to the mainline compiler and
it did not work.  Perhaps it would help if I illustrated the problem
in more detail.  GCC is not generating moves between integer and float
registers.  It is, however, generating 64-bit integer loads and stores
directly to floating point registers.  For example, given

typedef struct {
    int         a;
    int         b;
} my_struct;

extern my_struct a_st1;
extern my_struct a_st2;

void testFp1 (void)
    a_st1 = a_st2;

top of trunk cross compiler to powerpc-eabisim, -O2 -mregnames produces

	lis %r9,a_st2@ha
	lis %r11,a_st1@ha
	la %r9,a_st2@l(%r9)
	la %r11,a_st1@l(%r11)
	lfd %f0,0(%r9)
	stfd %f0,0(%r11)

[-mregnames simply aids readability; without it, the registers are
bare numbers.]

Compare what I get with -msoft-float too:

        lis %r9,a_st2@ha
        lis %r11,a_st1@ha
        la %r9,a_st2@l(%r9)
        la %r11,a_st1@l(%r11)
        lwz %r7,0(%r9)
        lwz %r8,4(%r9)
        stw %r7,0(%r11)
        stw %r8,4(%r11)

Now, the code I quoted above that uses floating point moves was
generated with REGISTER_MOVE_COST and MEMORY_MOVE_COST both tweaked to
make integer load/store to floating point registers cost 100 (other
values returned by *MOVE_COST are < 10). It doesn't seem to make any
difference.  The .lreg dump for the DImode pseudo causing the problem

Register 86 costs: BASE_REGS:200000 GENERAL_REGS:200000

Register 86 used 2 times across 2 insns in block 0; set 1 time;
	8 bytes; pref NON_SPECIAL_REGS.

-- _all_ the costs seem to have been multiplied by 100, compared to
   costs for other pseudos, e.g. this pointer

Register 85 costs: BASE_REGS:0 GENERAL_REGS:4000
	NON_FLOAT_REGS:4000 ALL_REGS:4000 MEM:12000

Register 85 used 2 times across 6 insns in block 0; set 1 time;
	pref BASE_REGS; pointer.

where FLOAT_REGS weren't even considered.  So either I misunderstood
the change you were suggesting, or the macros don't do what you
thought, or perhaps both.

More to the point, even if I could figure out how to get the MOVE_COST
macros to do what I want, I'm worried that it would be too weak a
prohibition.  The larger situation is, these compilers are being used
to build code for an embedded OS which does lazy FPU state saving.
Unfortunately it doesn't bother disabling the FPU for tasks that claim
not to need it.  (This is being taken up with the kernel developers.)
Therefore, a task that claims to be all integer code, but has had the
compiler use floating point registers behind its back, will corrupt
execution state for some random other process.

What we need out of GCC is a switch (we've been calling it
-fno-implicit-fp) which offers a guarantee that GCC will generate no
floating point instructions whatsoever for any function which does not
explicitly use floating point.  Per-translation-unit is not fine
grained enough, and calls to the nonexistent soft float library are
not wanted either - in other words, -msoft-float isn't what I'm
looking for.

I'm currently thinking of setting a flag somewhere that says "this
function uses floating point", and having HARD_REGNO_MODE_OK look at
that as well as the global flag_implicit_fp.


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