<html>
    <head>
      <base href="http://llvm.org/bugs/" />
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW --- - llvm generates pop pc on ARMv4 in thumb mode (broken interworking)"
   href="http://llvm.org/bugs/show_bug.cgi?id=16857">16857</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>llvm generates pop pc on ARMv4 in thumb mode (broken interworking)
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>3.3
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>LLVM Codegen
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>sven.koehler@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvmbugs@cs.uiuc.edu
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Command:
clang -target arm-softfloat-eabi -mcpu=arm7tdmi -mthumb -O2 -S -o - foo.c

Contents of foo.c:
#include <stdint.h>
int foo(int a, int64_t b, int64_t c) {
  return a + (int)(b/c);
}

Assembler code generated:
foo:
    push    {r4, r5, r6, r7, lr}
    add    r7, sp, #12
    sub    sp, #4
    mov    r4, r0
    ldr    r5, [sp, #24]
    ldr    r6, [sp, #28]
    mov    r0, r2
    mov    r1, r3
    mov    r2, r5
    mov    r3, r6
    bl    __aeabi_ldivmod
    adds    r0, r0, r4
    add    sp, #4
    pop    {r4, r5, r6, r7, pc}

Problem description:
If foo is called from thumb mode, then lr is an odd address. If foo is called
from arm mode, then lr is an even address. On ARMv4, the address popped to pc
must be even according to arm documentation:
<a href="http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0489i/Cihedhif.html">http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0489i/Cihedhif.html</a>
Also according to arm documentation, a pop pc (or ldmia sp!, pc) cannot be used
for switching between arm and thumb mode on ARMv4. Hence, the above assembler
code does not switch back to arm mode if the caller was arm mode. The bx
instruction has to be used to switch mode on ARMv4.

The code generated by gcc for ARMv4 looks something like this:
pop {r4, r5, r6, r7}
pop {r0}
bx r0

As far as I know, interworking is mandatory for arm-eabi. I tried using the
command line switch -mthumb-interwork to clang, but it is ignored.


Note that the code above doesn't work for ARMv4 at all since mov is used with
two low registers. I filed that as <a class="bz_bug_link 
          bz_status_NEW "
   title="NEW --- - llvm generates invalid mov command for arm7tdmi target"
   href="show_bug.cgi?id=16855">bug 16855</a>.</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>