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

Re: Better handling for multi-word values?


   Date: Fri, 4 Sep 1998 13:41:08 +0200 (MET DST)
   From: Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>

   Ideas, anyone?

Firstly, it is nice to see someone trying to look into these issues
;-)

You mention the adddi case on a 32-bit host.  You may want to look
into how I split these up in the 32-bit Sparc backend.  Essentially it
starts with:

[(set (match_operand:DI 0 "register_operand" "=r")
      (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
	       (match_operand:DI 2 "arith_double_operand" "rHI")))
 (clobber (reg:CC 100))]

The clobber is emitted by the adddi expander on 32-bit Sparc.
Then the forced split expansion gives something like:

[(parallel [(set (reg:CC_NOOV 100)
                 (compare:CC_NOOV (plus:SI (match_dup 4)
 					   (match_dup 5))
				  (const_int 0)))
            (set (match_dup 3)
                 (plus:SI (match_dup 4) (match_dup 5)))])
 (set (match_dup 6)
      (plus:SI (plus:SI (match_dup 7)
			(match_dup 8))
	       (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]

I am pointing this out because if you can find a way to make your
MULTIWORD mechanism express what I end up with above the adddi case
will be quite cleanly solvable.

I thought often about how the compiler could internally understand
that the above is a way that adddi could be performed on a SImode word
sized host.  This would involve adding code to check:

1) Can the host add two SImode values and record the resulting
   condition codes.
2) Can the host add two SImode values and also a carry condition
   created by the previous CC setting instruction.

The Sparc split above shows data dependency completely, but the
compiler really doesn't know what:

(ltu:SI (reg:CC_NOOV 100) (const_int 0))

means.  It knows that there are insns in the sparc MD file which match
it and which operands are inputs and outputs, but nothing more.

Next issue, I am about to embark on fixing some SUBREG issues in the
compiler.  In fact I am having dinner tonight with a few knowledgable
folks about the whole issue ;-)

The problem I need to solve is that for floating point on 64-bit Sparc
we have a bit of a problem.  The whole SUBREG_WORD mechanism defined a
word as the machines natural word size, DImode on 64-bit sparc.
However the FPU registers are still composed of:

1) 32-bit SFmode registers
2) 64-bit DFmode register pairs
3) 128-bit TFmode register quadruplets

The SFmode parts are the problematic ones.  We have all sorts of ugly
hacks for HARD_REGNO_NREGS, and ALTER_HARD_SUBREG which are not only
gross, they don't work at all.  One test case where this all falls
apart on 64-bit Sparc right now is taking a DFmode subreg of a double
complex value, consider:

(subreg:DF (reg:DC 32 %f0) 0)

Here %f0 has been allocated because it is an incoming argument
register in which the complex double has been passed.  However reload
blows up because it believes that this subreg cannot work and thus the
subreg must be reloaded with another hard register, here is the piece
of code in find_reloads() which causes this:

		  /* Subreg of a hard reg which can't handle the subreg's mode
		     or which would handle that mode in the wrong number of
		     registers for subregging to work.  */
		  || (GET_CODE (operand) == REG
		      && REGNO (operand) < FIRST_PSEUDO_REGISTER
		      && ((GET_MODE_SIZE (operand_mode[i]) <= UNITS_PER_WORD
			   && (GET_MODE_SIZE (GET_MODE (operand))
			       > UNITS_PER_WORD)
			   && ((GET_MODE_SIZE (GET_MODE (operand))
				/ UNITS_PER_WORD)
			       != HARD_REGNO_NREGS (REGNO (operand),
						    GET_MODE (operand))))
			  || ! HARD_REGNO_MODE_OK (REGNO (operand) + offset,
						   operand_mode[i]))))

(the end result is that reload uses an integer register %g2 for the
 subreg and then the original DFmode move no longer matches correctly
 and the compiler aborts)

The scheme we are going to investigate is removing SUBREG_WORD
entirely (in the end) and using something like SUBREG_BIT instead.

For other cases (mostly unions containing various float types) on
sparc64 we tried to use CLASS_CANNOT_CHANGE_SIZE to alleviate the
problems, but this was not a total solution either, eventually we
ended up hacking up the compiler to recognize less subreg types in the
move patterns.

Richard has contemplated removing SUBREG's completely, although I like
the idea I'm not ready right now to go in and make such a massive
change. :-)

Later,
David S. Miller
davem@dm.cobaltmicro.com



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