http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60039

--- Comment #6 from Valeriy E. Ushakov <uwe at netbsd dot org> ---
As far as I can tell the actual problem is in this code:

    .loc 1 189 0
    mov.l    .L91,r0
    ; ...
    add    r12,r0
    mov.l    .L84,r1
    jsr    @r0    ; udivsi3 for 32*1024/pagesz
     ; ...
    .loc 1 189 0
    bsrf    r1    ; morepages call
.LPCS6:
     mov    r0,r4    ; with result of division

.L91:
    .long    __udivsi3@GOTOFF
.L84:
    .long    morepages-(.LPCS6+2)

That code assumes that r1 is not clobbered, but in our case it is.
So instead of calling morepages() we end up with a small branch forward.
and pagepool_start is not initialized properly, causing SIGSEGV later.

I don't remember how we build udivsi3 &c bits in NetBSD, we might be
violating assumptions about clobbered regs.

FWIW, our in-tree gcc 4.5 generates for this:

        mov.l   .L75,r0
    ; ...
        mov.l   @(r0,r12),r2
        jsr     @r2
         ; ...
        mov.l   .L67,r1
        mov     r0,r4
        bsrf    r1
.LPCS6:

.L75:
        .long   __udivsi3_i4i@GOT
.L67:
        .long   morepages-(.LPCS6+2)

Because, as far as I can tell, in 4.5 sh_override_options() has an extra

    else if (TARGET_SH2)    /* ??? EXPERIMENTAL */
      sh_div_strategy = SH_DIV_CALL_TABLE;

clause, that is missing in 4.8 sh_option_override().

Reply via email to