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