Hi, I need to use a scratch register in the "jump" pattern and I can't figure out how to do it properly.
My problem is that the microcontroller I'm porting gcc onto does not permit "far" jumps, those must be done using an indirect adressing. So I wrote this: -----------------8<----------------------8<----------------- (define_attr "length" "" (const_int 2)) (define_insn "*jump" [(set (pc) (label_ref (match_operand 0 "" ""))) (clobber (match_scratch:QI 1 "=r"))] "" { if (get_attr_length (insn) == 1) return "rjmp %0"; else return "ldih %1,hi(%l0)\n\t\n\tldil %%1,lo(%l0)\n\tijmp %(%1)"; } [(set (attr "length") (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -2048)) (le (minus (match_dup 0) (pc)) (const_int 2047))) (const_int 1) (const_int 2)))] ) (define_expand "jump" [(set (pc) (label_ref (match_operand 0 "" "")))] "" "" ) -----------------8<----------------------8<----------------- But it doesn't work: ... (jump_insn 44 266 45 6 /tmp/src/gcc-4.3.1/libgcc/../gcc/libgcov.c:137 (set (pc) (label_ref 119)) -1 (nil)) /tmp/src/gcc-4.3.1/libgcc/../gcc/libgcov.c:577: internal compiler error: in extract_insn, at recog.c:1990 Please submit a full bug report, with preprocessed source if appropriate. Any idea ? Side question regarding the "length" attribute. It seems to work ok, but if I change the default value (first line in my example) to be 'const_int 1', I later get 'operand out of range' from the assembler because the 'rjmp' instruction was used for deplacements bigger than 2048. How can this happen, since my '(set (attr "length")' code explicitly sets the correct value each time ? Thanks, -- Stelian Pop <stel...@popies.net>