Porting gcc for F-CPU without direct JMP

Jan Hubicka jh@suse.cz
Tue Dec 10 09:59:00 GMT 2002

> Hello,
> I just tried to port GCC 3.2 to free CPU design
> (www.f-cpu.org). The cpu is different in sense that
> there is no direct jump (only indirect jump to preloaded
> address in register).
> When I use:
> ;;(define_expand "jump"
> ;; [(set (match_dup 1) (label_ref (match_operand:QI 0 "" "")))
> ;;  (set (pc) (match_dup 1))]
> ;;  "" "operands[1]=gen_reg_rtx(Pmode);")
> it fails during jump optimization while simplifying complex
> jumps into simpler ones - endless loop ! I break it:
> #0  0x080c120e in gen_sequence () at emit-rtl.c:4620
> #1  0x081176bc in gen_jump (operand0=0x4014f708) at insn-emit.c:1392
> #2  0x080a63ed in try_redirect_by_replacing_jump (e=0x82d61ac,
> target=0x82d60f0) at cfgrtl.c:735
> #3  0x080a6632 in redirect_edge_and_branch (e=0x82d61ac, target=0x82d60f0)
> at cfgrtl.c:832
> #4  0x081b10ef in try_optimize_cfg (mode=17) at cfgcleanup.c:1658
> Basically it prevents all non-constant target jumps to be optimized
> because jump redirecting needs to change the label constant in jump insn.
> Handling jump at assembler is not the ideal way because the
> address load insn has some latency which can be hidden by
> gcc scheduler. Also it can pull invariant address load out
> of the loops.
> I was thinking (and I'd appreciate your comments) about changing
> jump.c in such way that it looks for appropriate label constant
> load insn (probably pointer from jump insn) and does the label change
> there.
> But I'm not sure if is it enough :( Can someone give me some
> hints ?
Representing jumps as indirect jumps won't work.  Indirect jumps are
different from direct jumps in a way that they create abnormal edges.
No one expect from try_redirect functions to introduce these.  Even if
this worked, it will be overkill performance wise - GCC will
lose track of what is going on and build complete graph as CFG for each
function breaking most of optimizations.

BTW how it can get into redirecting of edges when all jumps in the
functions are indirect?  Can you take a look how does the flowgraph look

I beleive only sane way is to hide the fact that register is needed
behind the compiler as far as possible.  Probably first insn splitting
pass should introduce the clobbers for address loads and these should
be emit in second insn splitting pass.
This still loses for loops as jump address load can be hoisted outside,
but for getting the port working it may be good enought and we can
improve code quality later.

> thanks, devik

More information about the Gcc mailing list