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