Omar <[EMAIL PROTECTED]> writes:
>  1-The c816's port is heavily using the c816.c instead of better
> describing the cpu in the c816.md file. For instance, looking at the
> define_insn movhi:
> ;; movhi
> (define_insn "movhi"
>  [(set (match_operand:HI 0 "general_operand" "=g")
>        (match_operand:HI 1 "general_operand" "g"))]
>  ""
>  "*
>        {
>          return output_move(insn, operands);
>        }
>  ")
>
>  I noticed that predicates and constraints are essentially disabled,
> and the output_move function in the c816.c  does all the work. Also,
> since c816 can only move bytes, it looks to me like this definition is
> incorrectly since it is basically lying to gcc and making it believe
> that there is a two byte move. Is a define_split (or a define_expand)
> more appropriate in this situation?

A define_split has traditionally been the best way, yes.  The splitter
would normally be a postreload one (i.e. it would normally be conditional
on reload_completed).

There's no real point doing a define_expand, unless it needs to do
something particularly magical.  If there is no move pattern for a
wide mode, emit_move_insn & friends can break it up into narrower
pieces.

>  2- I am trying to sort-out define_expand from define_split. Looks
> like they can be used to perform similar tasks. By looking at other
> ports I came to the following conclusions (I gather this from reading
> multiple posts, please correct me if this statements are not true):
>  2.1  define_split should be used to break an operation into simpler
> operations *of a different mode*. That is, to describe a movhi in
> terms of two movqi I should use a define_split instead of a
> define_expand.
>  2.2 the define_expand expects the mode of the matching rtl macro and
> the output operations to be preserve. Otherwise gcc could get confuse
> since the mode will be change for no apparent reason.

To answer the question directly first: define_splits don't need to
operate on different modes.  Sometimes you have a define_insn with
several (constraint) alternatives, some of which map to a single
instruction and some of which map to several instructions.  You can
then use a define_split to split up the multi-instruction alternatives.

As far as define_expands go: named instructions like "addhi3" must
implement the addition of two given HImode values and store the result
in a given HImode location.  The expander is free to implement the
operation however it likes within those constraints.

The difference between define_expands and define_splits is really
one of timing.  define_expands are applied immediately, so the
optimisers can see the individual instructions straight away.
This can make some optimisations harder and others easier.

define_splits are applied later, and were traditionally used to
"lower" multiword operations into word operations.  The idea was
to let the higher-level rtl optimisers see the complete multiword
operation (like a DImode addition on a 32-bit target) and let the
later, lower-level optimisations see the individual word-mode
operations.

However, most of the interesting higher-level, multiword optimisations
now happen at the tree level.  The higher-level rtl stuff is mostly for
port-specific things like address logic.  (OK, so that's a fairly big
generalisation.)

The MIPS port used to have define_splits for multiword operations,
but I found after tree-ssa that we got better code by expanding into
individual instructions immediately.  optabs knows how to decompose
most multiword operations, so you'll only need your own define_expand if
your target has a feature that is not associated with a named pattern.
E.g. ports with an "add-with-carry" instruction might implement a
doubleword addition pattern, but those that can't better an add-and-shift-
based sequence don't need to.

There's a second use of define_splits that you don't mention explicitly:
they allow the "combine" pass to decompose a single, unrecognisable
operation into instructions that are recognisable.  define_expands
are not used for this.

Also, define_expands can be useful if you want to implement a named
pattern in more than one way, perhaps depending on command-line options.
You can only have one pattern called "addsi3", but if you make it a
define_expand, you can emit any specific define_insn you like.
Some of the define_insns might have more clobbers than others,
for example.

Probably most of that was just telling you what you already knew, sorry.
Good luck with the port,

Richard

Reply via email to