Peter,
Thanks for the reply.
Now I understand why it looked like it was placing a prolog on the
assembled code it makes sense.
And yes removing the C statements is required as I expected.
Regards
Chris Healy
On 14/11/12 23:04, Peter Bigot wrote:
The naked is not being ignored there. gcc doesn't introspect the
contents of asm statement templates, so it's obliged to save the
incoming registers on the stack before the first asm statement in case
they were corrupted. This is not the same as emitting a prolog and
epilog, which naked inhibits.
Apparently with -O1 gcc is willing to presume that that r14 and r15
are not clobbered (since the asm statement doesn't mention them
outside the template, which is not parsed), so skips the save.
Based on what I can see line 38 is not superfluous: you specify that
variable sp is a register input to the asm statement, and gcc chose to
put it into r15 for that purpose. If you use the operand in the
template, it's not the snippet you've shown.
The documentation for "naked" that you quote is for other back ends,
but is fairly descriptive of expectations for mspgcc. The code you
show violates its contract in two ways: it interleaves asm statements
with C statements, and it uses operands in an asm statement.
In short, while it may not be doing what you expect, I don't see that
it's doing anything wrong.
Peter
On Wed, Nov 14, 2012 at 4:41 AM, Chris <chrishe...@internode.on.net
<mailto:chrishe...@internode.on.net>> wrote:
I am not sure if this is by design or otherwise, but I was trying to
compile some MSP430 code that used the naked attribute for a function
and found that if -O0 optimization was set for the compile, the
attribute was ignored resulting in non functional code. For -O1 or -Os
the expected code was generated.
The code is like this .
__attribute__((naked, weak))
void port_switch(Thread *ntp, Thread *otp) {
register struct intctx *sp asm("r1");
asm volatile ("push r11 \n\t" \
"push r10 \n\t" \
........
"push r4" : : : "memory");
otp->p_ctx.sp = sp;
sp = ntp->p_ctx.sp;
asm volatile ("pop r4 \n\t" \
"pop r5 \n\t" \
...........
"pop r11 \n\t" \
"ret" : : "r" (sp) : "memory");
}
And with -O0 the lst looks like this which is definitely not
functional.
14 port_switch:
15 .LFB0:
16 .file 1
"../../os/ports/GCC/MSP430/chcore.c"
17 .loc 1 47 0
18 0000 814F 0000 mov r15, @r1
19 0004 814E 0200 mov r14, 2(r1)
20 .loc 1 50 0
21 #APP
22 ; 50 "../../os/ports/GCC/MSP430/chcore.c" 1
23 0008 0B12 push r11
............
30 0016 0412 push r4
31 ; 0 "" 2
32 .loc 1 58 0
33 #NOAPP
34 0018 0E41 mov r1, r14
35 001a 1F41 0200 mov 2(r1), r15
36 001e 8F4E 0600 mov r14, 6(r15)
37 .loc 1 60 0
38 0022 2F41 mov @r1, r15
39 0024 1F4F 0600 mov 6(r15), r15
40 0028 014F mov r15, r1
41 .loc 1 62 0
42 002a 0F41 mov r1, r15
43 #APP
44 ; 62 "../../os/ports/GCC/MSP430/chcore.c" 1
45 002c 3441 pop r4
....................................
If the naked is removed, the compiler produces identical code as -O0 +
naked.
For -O1 the code lst is like this.
14 port_switch:
15 .LFB0:
16 .file 1
"../../os/ports/GCC/MSP430/chcore.c"
17 .loc 1 47 0
18 .LVL0:
19 .loc 1 50 0
20 #APP
21 ; 50 "../..//os/ports/GCC/MSP430/chcore.c" 1
22 0000 0B12 push r11
............
29 000e 0412 push r4
30 ; 0 "" 2
31 .loc 1 58 0
32 #NOAPP
33 0010 8E41 0600 mov r1, 6(r14)
34 .loc 1 60 0
35 0014 114F 0600 mov 6(r15), r1
36 .LVL1:
37 .loc 1 62 0
38 0018 0F41 mov r1, r15
39 .LVL2:
40 #APP
41 ; 62 "../../os/ports/GCC/MSP430/chcore.c" 1
42 001a 3441 pop r4
.................
49 0028 3B41 pop r11
50 002a 3041 ret
Which is what is required although line 38 is superfluous.
Information on naked is a bit difficult to come by. The GCC manual
states.
|naked|
Use this attribute on the ARM, AVR, MCORE, RX and SPU ports to
indicate that the specified function does not need
prologue/epilogue
sequences generated by the compiler. It is up to the programmer to
provide these sequences. The only statements that can be safely
included in naked functions are |asm| statements that do not have
operands. All other statements, including declarations of local
variables, |if| statements, and so forth, should be avoided. Naked
functions should be used to implement the body of an assembly
function, while allowing the compiler to construct the requisite
function declaration for the assembler.
So perhaps it was expecting a bit much for this code to produce the
correct machine code.
But that aside, when the C code is replaced with assembler, there
would
still be unintended writes to the stack.
Regards
Chris Healy
------------------------------------------------------------------------------
Monitor your physical, virtual and cloud infrastructure from a single
web console. Get in-depth insight into apps, servers, databases,
vmware,
SAP, cloud infrastructure, etc. Download 30-day Free Trial.
Pricing starts from $795 for 25 servers or applications!
http://p.sf.net/sfu/zoho_dev2dev_nov
_______________________________________________
Mspgcc-users mailing list
Mspgcc-users@lists.sourceforge.net
<mailto:Mspgcc-users@lists.sourceforge.net>
https://lists.sourceforge.net/lists/listinfo/mspgcc-users
------------------------------------------------------------------------------
Monitor your physical, virtual and cloud infrastructure from a single
web console. Get in-depth insight into apps, servers, databases, vmware,
SAP, cloud infrastructure, etc. Download 30-day Free Trial.
Pricing starts from $795 for 25 servers or applications!
http://p.sf.net/sfu/zoho_dev2dev_nov
_______________________________________________
Mspgcc-users mailing list
Mspgcc-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mspgcc-users