Re: [avr-gcc-list] AVR C calling convention not matching spec

2016-12-20 Thread Dylan McKay
I think you're correct.

When I use the on-chip test tool, linking LLVM generated code to GCC
generated code, everything works fine, even when I have multiple 64-bit
arguments being passed.

Thanks for the help Pitchumani!

On Tue, Dec 20, 2016 at 5:54 AM, Pitchumani Sivanupandi <
pitchumani.sivanupa...@microchip.com> wrote:

> On Sunday 11 December 2016 07:13 AM, Dylan McKay wrote:
>
>> Hey all,
>>
>> I'm working on the AVR backend for LLVM.
>>
>> I'm looking into an issue where the current LLVM implementation of the
>> AVR C calling convention is not matching the assembly of what GCC is
>> generating.
>>
>> On top of that, when I run through the argument algorithm described on
>> the Wiki (https://gcc.gnu.org/wiki/avr-gcc), GCC output doesn't seem to
>> match up, whereas LLVM does.
>>
>> The shortest and most inaccurate version of it is: GCC only stores up to
>> 8 bytes of arguments in registers, and every argument after that is located
>> on the stack. The Wiki says that registers between r8-r25 are used, which
>> doesn't seem to match up.
>>
>> Example: Given a function which takes two 64-bit integers (i64 %a, i64 %b)
>> * Start with Rn = 26 * Begin processing %a * Rn -= 8 = 18 * Rn >= 8,
>> therefore this argument will be stored in registers r18-r25 * Begin
>> processing %b * Rn -= 8 = 10 * Rn >= 8, therefore this argument will be
>> stored in registers r10-r17
>> This indicates that both arguments should be located in registers, but
>> AVR-GCC stores the first argument in registers, and the second argument on
>> the stack.
>>
>> Which is correct? Am I misunderstanding the algorithm?
>>
>> Where in GCC can I find the implementation of this calling convention?
>>
>> I've got an issue on the LLVM bug tracker here (
>> https://llvm.org/bugs/show_bug.cgi?id=31347).
>>
>
> I guess you misunderstood the assembly generated.
> (snip)
> .global thing
> .type   thing, @function
> thing:
> push r10 <--
> push r11
> push r12
> push r13 save call-used registers
> push r14
> push r15
> push r16
> push r17 -->
> /* prologue: function */
> /* frame size = 0 */
> /* stack size = 8 */
> .L__stack_usage = 8
> ldi r30,lo8(4);
> ldi r31,0 ; load address 4 to Z register
> st Z,r10 <-
> std Z+1,r11
> std Z+2,r12
> std Z+3,r13
> std Z+4,r14  store argument b (which is in r10-r17)
> std Z+5,r15  into memory starts at 4 (4-11)
> std Z+6,r16
> std Z+7,r17  ->
> /* epilogue start */
> pop r17  <
> pop r16
> pop r15
> pop r14
> pop r13  restore call-used registers
> pop r12
> pop r11
> pop r10  ->
> ret
> .size   thing, .-thing
> (snip)
>
> Regards,
> Pitchumani
>
___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list


Re: [avr-gcc-list] AVR C calling convention not matching spec

2016-12-19 Thread Pitchumani Sivanupandi

On Sunday 11 December 2016 07:13 AM, Dylan McKay wrote:

Hey all,

I'm working on the AVR backend for LLVM.

I'm looking into an issue where the current LLVM implementation of the 
AVR C calling convention is not matching the assembly of what GCC is 
generating.


On top of that, when I run through the argument algorithm described on 
the Wiki (https://gcc.gnu.org/wiki/avr-gcc), GCC output doesn't seem 
to match up, whereas LLVM does.


The shortest and most inaccurate version of it is: GCC only stores up 
to 8 bytes of arguments in registers, and every argument after that is 
located on the stack. The Wiki says that registers between r8-r25 are 
used, which doesn't seem to match up.


Example: Given a function which takes two 64-bit integers (i64 %a, i64 %b)
* Start with Rn = 26 * Begin processing %a * Rn -= 8 = 18 * Rn >= 8, 
therefore this argument will be stored in registers r18-r25 * Begin 
processing %b * Rn -= 8 = 10 * Rn >= 8, therefore this argument will 
be stored in registers r10-r17
This indicates that both arguments should be located in registers, but 
AVR-GCC stores the first argument in registers, and the second 
argument on the stack.


Which is correct? Am I misunderstanding the algorithm?

Where in GCC can I find the implementation of this calling convention?

I've got an issue on the LLVM bug tracker here 
(https://llvm.org/bugs/show_bug.cgi?id=31347).


I guess you misunderstood the assembly generated.
(snip)
.global thing
.type   thing, @function
thing:
push r10 <--
push r11
push r12
push r13 save call-used registers
push r14
push r15
push r16
push r17 -->
/* prologue: function */
/* frame size = 0 */
/* stack size = 8 */
.L__stack_usage = 8
ldi r30,lo8(4);
ldi r31,0 ; load address 4 to Z register
st Z,r10 <-
std Z+1,r11
std Z+2,r12
std Z+3,r13
std Z+4,r14  store argument b (which is in r10-r17)
std Z+5,r15  into memory starts at 4 (4-11)
std Z+6,r16
std Z+7,r17  ->
/* epilogue start */
pop r17  <
pop r16
pop r15
pop r14
pop r13  restore call-used registers
pop r12
pop r11
pop r10  ->
ret
.size   thing, .-thing
(snip)

Regards,
Pitchumani

___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list