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().