title: Different function call assemblywith -O0 and -O1 with GCC on ARM
body: <p>I would like to call an assembly function from C. It is part of a basic example for calling conventions.</p>
  
  <p>The function is a basic:</p>
  
  <pre><code>int mult(int A, int B){
      return A*B
  }
  </code></pre>
  
  <p>According to the <a href="http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042f/IHI0042F_aapcs.pdf" rel="nofollow noreferrer">Procedure Call Standard for the
  ARM® Architecture</a> the parameters <code>A</code> and <code>B</code> should be in registers <code>r0</code> and <code>r1</code> respectively for the function call. The return value should be in <code>r0</code>.</p>
  
  <p>Essentially then I would expect the function to be:</p>
  
  <pre><code>EXPORT mult
  mult MULT r0, r0, r1
       BX lr
  </code></pre>
  
  <p>With GCC 7.2.1 (none) -O1 -mcpu=cortex-m4 -mabi=aapcs,  I get the following: <a href="https://godbolt.org" rel="nofollow noreferrer">(using Compiler Explorer)</a></p>
  
  <pre><code>mult:
      mul     r0, r1, r0
      bx      lr
  </code></pre>
  
  <p>Which is what I expected. However. If I disable optimizations (-O0) I get the following nonsense:</p>
  
  <pre><code>mult:
      push    {r7}
      sub     sp, sp, #12
      add     r7, sp, #0
      str     r0, [r7, #4]
      str     r1, [r7]
      ldr     r3, [r7, #4]
      ldr     r2, [r7]
      mul     r3, r2, r3
      mov     r0, r3
      adds    r7, r7, #12
      mov     sp, r7
      pop     {r7}
      bx      lr
  </code></pre>
  
  <p>Which means GCC is using <code>r7</code> as a frame pointer I think and passing <em>all</em> of the parameters and return values via the stack. Which is not according to the AAPCS.</p>
  
  <p>Is this a bug with Compiler Explorer, GCC or have I missed something in the AAPCS? Why would -O0 have a fundamentally different calling convention than specified in the AAPCS document?</p>