Stelian Pop schrieb:
On Tue, Mar 10, 2009 at 10:18:10PM +0100, Georg-Johann Lay wrote:
Note that no one is generating an insn that looks like "*jump". Maybe
insn combine and peep2 would try to build such a pattern, but that is
not what helpd you out here. Write the expander as parallel of a (set
(pc) ...) and a (clobber (match_scratch ...)) so that an appropriate
insn is expanded.
Like this ?
(define_expand "jump"
[(parallel [(set (pc) (label_ref (match_operand 0 "" "")))
(clobber (match_scratch:QI 1 "=&r"))])]
""
""
)
Constraints are useless in expanders. You really need a QI scratch? Your
insn looks as if HI was needed as you load hi and lo part of the scratch.
Also note that "*jump" is an (implicit) parallel. As
constraint for the "*jump" insn use an "X" in the case you do not need
the clobber reg and sth. like "=&r" in the case you really need it.
Ok, but the decision on if I need the clobber reg or not is based
on the 'length' attribute. So if I could write the following, but where
I can put the calculation and the test of the 'length' attribute:
(define_insn "*jump_internal"
[(set (pc)
(label_ref (match_operand 0 "" "")))
(clobber (match_scratch:QI 1 "X,=&r"))]
""
"@
rjmp %0
ldih %1,hi(%l0)\n\t\n\tldil %1,lo(%l0)\n\tijmp (%1)"
)
You cannot destinguish the two cases by means of constraints; computing
jump distances is not yet known in global alloc. I guess reload will
always take the first alternative: In your example #0 has no
constraints. Same would apply if constraints #1 were same as constraints
#1).
So you have just one alternative "=&r", and in the case of rjmp the
scratch is unused. Note that you emit up to three instructions, so the
-2048/2047 may crash in corner cases.
You can have a look at avr, it computes jump lengths as well but afaIr
without needing a scratch for long jumps.
Georg-Johann