svn commit: r258412 - in head/sys/arm: at91 econa s3c2xx0 sa11x0 xscale/i80321 xscale/i8134x xscale/ixp425 xscale/pxa

John-Mark Gurney jmg at funkthat.com
Sat Jan 11 00:26:50 UTC 2014


Ian Lepore wrote this message on Fri, Jan 10, 2014 at 16:41 -0700:
> On Fri, 2014-01-10 at 15:02 -0800, John-Mark Gurney wrote:
> > John-Mark Gurney wrote this message on Wed, Jan 08, 2014 at 09:39 -0800:
> > > So, I've tested that HEAD (absolutely no tree changes) w/
> > > WITHOUT_ARM_EABI boots fine...  and just to make sure my test is
> > > correct, I've disabled it too to verify that the kernel just hangs
> > > (absolutely no output)..  and reenabled it and verified it works (that
> > > my setting is changing something)...
> > > worky -> no worky -> worky...
> > > 
> > > Now I just realized another interesting thing about setting
> > > WITHOUT_ARM_EABI, it also fixes the console issue I was having w/ your
> > > call to cpu_setup("") previously (w/ EABI) killing console output and
> > > not even seeing the mtx panic message...
> > > 
> > > So, it is clearly changing something very early on in boot...
> > 
> > Apparently gcc ARMEB w/ EABI miscompiles code...  The code to store
> > lo_flags in the lock_object is correct:
> >                         lock->lo_flags = i << LO_CLASSSHIFT;
> > c03ce2d0:       e1a01c06        lsl     r1, r6, #24
> > c03ce2d4:       e5881004        str     r1, [r8, #4]
> > 
> > But when I add a printf to fetch the data, I get:
> > printf("lo_classindex: %#x\n", LO_CLASSINDEX(lock));
> > c03ce2e0:       e5d81007        ldrb    r1, [r8, #7]
> > c03ce2e4:       e59f0098        ldr     r0, [pc, #152]  ; c03ce384 <_end+0xffcf9
> > 19c>
> > c03ce2e8:       e201100f        and     r1, r1, #15     ; 0xf
> > c03ce2ec:       eb0012ea        bl      c03d2e9c <printf>
> > 
> > 
> > We are doing a ldrb (LoaD Relative Byte) which would be fine to
> > substitute for the right shift of 24, but only if it loaded the correct
> > byte.. It should be loading #4 instead of #7 since we are on big
> > endian...
> > 
> > Anyone who know gcc arm well to figure this out?
> > 
> 
> The generated byte-load code is enough different from the literal "load
> 32 bits and shift" of LO_CLASSINDEX() that the optimizer must have
> messed it up.  Do we build the kernel with -O2, and if so would -O1
> help?

In a generated test case, even -O1 produces broken code... Only -O0
looks like it produces correct code, though the code is so much more
verbose, it takes more work to verify...

code:
int
foo(int *b)
{
        return (*b & 0xf000000) >> 24;
}

-O0:
00000000 <foo>:
   0:   e1a0c00d        mov     ip, sp
   4:   e92dd800        push    {fp, ip, lr, pc}
   8:   e24cb004        sub     fp, ip, #4      ; 0x4
   c:   e24dd004        sub     sp, sp, #4      ; 0x4
  10:   e50b0010        str     r0, [fp, #-16]
  14:   e51b3010        ldr     r3, [fp, #-16]
  18:   e5933000        ldr     r3, [r3]
  1c:   e203340f        and     r3, r3, #251658240      ; 0xf000000
  20:   e1a03c43        asr     r3, r3, #24
  24:   e1a00003        mov     r0, r3
  28:   e89da808        ldm     sp, {r3, fp, sp, pc}

-O1 & -O2:
00000000 <foo>:
   0:   e5d00000        ldrb    r0, [r0]
   4:   e200000f        and     r0, r0, #15     ; 0xf
   8:   e12fff1e        bx      lr

-- 
  John-Mark Gurney				Voice: +1 415 225 5579

     "All that I will do, has been done, All that I have, has not."


More information about the freebsd-arm mailing list