[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
RE: [avr-gcc-list] movw and asm
From: |
Rune Christensen |
Subject: |
RE: [avr-gcc-list] movw and asm |
Date: |
Wed, 6 Aug 2003 17:55:28 +0200 |
Hello
I have created a small file called test.c
inline unsigned long Test(unsigned long Input)
{
unsigned long Output;
asm
(
"mov %A0,%A1\n\t"
"mov %B0,%B1\n\t"
"mov %C0,%C1\n\t"
"mov %D0,%D1\n\t"
:"=r"(Output)
:"r"(Input)
);
return Output;
}
Try avr-gcc -Os -S test.c
.file "test.c"
.arch avr2
__SREG__ = 0x3f
__SP_H__ = 0x3e
__SP_L__ = 0x3d
__tmp_reg__ = 0
__zero_reg__ = 1
.global __do_copy_data
.global __do_clear_bss
.text
.global Test
.type Test, @function
Test:
/* prologue: frame size=0 */
/* prologue end (size=0) */
mov r27,r25
mov r26,r24
mov r25,r23
mov r24,r22
/* #APP */
mov r24,r24
mov r25,r25
mov r26,r26
mov r27,r27
/* #NOAPP */
mov r22,r24
mov r23,r25
mov r24,r26
mov r25,r27
/* epilogue: frame size=0 */
ret
/* epilogue end (size=1) */
/* function Test size 19 (18) */
.size Test, .-Test
/* File "test.c": code 19 = 0x0013 ( 18), prologues 0, epilogues 1 */
Then I created the test2.c file
inline unsigned long Test(unsigned long Input)
{
unsigned long Output;
asm
(
"movw %A0,%A1\n\t"
"movw %C0,%C1\n\t"
:"=r"(Output)
:"r"(Input)
);
return Output;
}
Output from avr-gcc -Os -S test2.c
.file "test2.c"
.arch avr2
__SREG__ = 0x3f
__SP_H__ = 0x3e
__SP_L__ = 0x3d
__tmp_reg__ = 0
__zero_reg__ = 1
.global __do_copy_data
.global __do_clear_bss
.text
.global Test
.type Test, @function
Test:
/* prologue: frame size=0 */
/* prologue end (size=0) */
mov r27,r25
mov r26,r24
mov r25,r23
mov r24,r22
/* #APP */
movw r24,r24
movw r26,r26
/* #NOAPP */
mov r22,r24
mov r23,r25
mov r24,r26
mov r25,r27
/* epilogue: frame size=0 */
ret
/* epilogue end (size=1) */
/* function Test size 15 (14) */
.size Test, .-Test
/* File "test2.c": code 15 = 0x000f ( 14), prologues 0, epilogues 1
*/
Can anyone tell me why the 8 mov are not removed by the optimization ??
The minimum solution for the example would be
_Test:
movw r22, r22
movw r24, r24
ret
Best Regards
Rune Christensen
-----Original Message-----
From: James Dabbs [mailto:address@hidden
Sent: Wednesday, August 06, 2003 5:35 PM
To: 'address@hidden'; address@hidden
Subject: RE: [avr-gcc-list] movw and asm
> I found the following from the avr-libc-manual
>
> * Function call conventions:
> Arguments - allocated left to right, r25 to r8. All arguments are aligned
to
> start in even-numbered registers (odd-sized arguments, including char,
have one
> free register above them). This allows making better use of the movw
instruction
> on the enhanced core. If too many, those that don't fit are passed on the
stack. Return
> values: 8-bit in r24 (not r25!), 16-bit in r25:r24, up to 32 bits in
r22-r25, up to
> 64 bits in r18-r25. 8-bit return values are zero/sign-extended to 16 bits
by the
> caller (unsigned char is more efficient than signed char - just clr r25).
Arguments
> to functions with variable argument lists (printf etc.) are all passed on
stack, and
> char is extended to int.
Thanks Rune! These links are helpful, and they answered my next question.
But I am still wondering about parameters passed into asm blocks. For
instance..
inline unsigned long Test(unsigned long Input)
{
unsigned long Output;
Input = ((Input << 4) ^ (Input >> 5)) + Input;
asm
(
"mov %A0,%A1\n\t"
"mov %B0,%B1\n\t"
"mov %C0,%C1\n\t"
"mov %D0,%D1\n\t"
:"=r"(Output)
:"r"(Input)
);
Output = Output << 4;
return Output;
}
Is there is any determinism in how the compiler arranges the 8 registers
used to hold "Output" and "Input" before it falls into the asm block? I'm
also looking to see if there is a trick to emit conditional statements to
gas, like "if A0 and A1 are even registers and B0 and B1 are adjacent to
them then use movd" or whatever.
At this point, we met the benchmark by writing the whole routine over in
assembler. However, I'd still like to know. Atmel added movd to their
enhanced core.. It would be nice to be able to make use of it.