https://bugs.kde.org/show_bug.cgi?id=384442

--- Comment #3 from John Reiser <jrei...@bitwagon.com> ---
Here is the output from "--trace-flags=10000000", condensed and commented:
=====
        (arm) 0x49BD90C:  mov r12, r13
        (arm) 0x49BD910:  stmdb r13!, {0xDFF0}
        (arm) 0x49BD914:  sub r11, r12, #0x4
        (arm) 0x49BD918:  ldmdb r11, {0xAFF0}

              ------ IMark(0x49BD918, 4, 0) ------
              t8 = GET:I32(52 /*r11*/)
              t9 = t8
              PUT(68 /*r15,pc*/) = LDle:I32(Sub32(t9,0x4:I32))  // updated pc
no longer points to the 'ldmdb'
              PUT(60 /*r13,sp*/) = LDle:I32(Sub32(t9,0x8:I32))  // updated sp
              PUT(48 /*r10*/) = LDle:I32(Sub32(t9,0x10:I32))  // fetch from
wrong side of *updated* sp
              PUT(44 /*r9*/) = LDle:I32(Sub32(t9,0x14:I32))
              PUT(40 /*r8*/) = LDle:I32(Sub32(t9,0x18:I32))
              PUT(36 /*r7*/) = LDle:I32(Sub32(t9,0x1C:I32))
              PUT(32 /*r6*/) = LDle:I32(Sub32(t9,0x20:I32))
              PUT(28 /*r5*/) = LDle:I32(Sub32(t9,0x24:I32))
              PUT(24 /*r4*/) = LDle:I32(Sub32(t9,0x28:I32))
              PUT(52 /*r11*/) = LDle:I32(Sub32(t9,0xC:I32))
              PUT(68 /*r15,pc*/) = GET:I32(68)
              PUT(68 /*r15,pc*/) = GET:I32(68); exit-Boring

GuestBytes 49BD90C 16  0D C0 A0 E1 F0 DF 2D E9 04 B0 4C E2 F0 AF 1B E9 
0028F343

VexExpansionRatio 16 952   595 :10

==26904== Invalid read of size 4
==26904==    at 0x40054EC: ??? (in /lib/ld-uClibc-0.9.33.2.so)  ## pc should be
0x49BD918
==26904==  Address 0x7dad0654 is on thread 1's stack
==26904==  20 bytes below stack pointer  ## below updated sp, but above
original sp; should be no complaint
==26904==

=====
(Of course the original [user] compiler code generator could do much better.)

The VEX code in mk_ldm_stm() claims
===== priv/guest_arm_toIR.c  near line 14138
   if (bW == 0 && (regList & (1<<rN)) != 0) {
      /* Non-writeback, and basereg is to be transferred.  Do its
         transfer last for a load and first for a store.  Requires
         reordering xOff/xReg. */
=====
but I don't understand why.  The earlier
              t8 = GET:I32(52 /*r11*/)
              t9 = t8
has de-coupled the original value of the base register from any interaction
with subsequent code that deals with the register list.

The real problem is that the new values of r15(==pc) and r13(==sp) have been
written while the original values still are needed to detect fetching from the
wrong side of sp (via LDle:I32() for each remaining register), and for
reporting the pc of any complaint.  It is the writing of pc and sp that should
be re-ordered; and if both sp and pc are written then the generated code will
require another temporary variable to hold the new value of pc until after
there is no possibility of a complaint about this instruction.

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to