<html>
    <head>
      <base href="https://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 --- - AVR-GCC calling convention mismatch with stack"
   href="https://llvm.org/bugs/show_bug.cgi?id=31347">31347</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>AVR-GCC calling convention mismatch with stack
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libraries
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

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

        <tr>
          <th>OS</th>
          <td>All
          </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>Backend: AVR
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>dylanmckay34@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>The calling convention for picking registers for arguments is described at
(<a href="https://gcc.gnu.org/wiki/avr-gcc">https://gcc.gnu.org/wiki/avr-gcc</a>).

I've found a mismatch between when AVR-GCC loads arguments from the stack, and
when we do.

AVR-GCC Test case:
avr-gcc -S tmp.c -o tmp.s -O2


#include <stdint.h>

typedef uint8_t i8;
typedef uint16_t i16;
typedef uint32_t i32;
typedef uint64_t i64;

void thing(i64 a, i64 b) {
  *((i64*)0x4) = b;
}

This generates the following assembly to load argument 'b' from the stack

/* prologue: function */
/* frame size = 0 */
/* stack size = 8 */
.L__stack_usage = 8
    ldi r30,lo8(4)
    ldi r31,0
    st Z,r10
    std Z+1,r11
    std Z+2,r12
    std Z+3,r13
    std Z+4,r14
    std Z+5,r15
    std Z+6,r16
    std Z+7,r17

AVR-LLVM example:

define void @ret_void_args_i64_i64(i64 %a, i64 %b) {
  store volatile i64 %b, i64* inttoptr (i64 4 to i64*)
  ret void
}

This generates the following assembly:


        sts     4, r18
        sts     11, r17
        sts     10, r16
        sts     9, r15
        sts     8, r14
        sts     7, r13
        sts     6, r12
        sts     5, r11
        sts     4, r10
        ret

Clearly, we aren't following the calling convention in this case. We should be
loading 'b' from the stack.

This will break programs which take large numbers/big arguments on the stack.</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>