Weird SPSR behaviour

I was trying to write a register context saving/restoring when I came across a weird behaviour.

My code (sorry, tried to format tens of times, but the editor WANTS to make asm a table):

asm volatile (
...
"pop {r0 - r3}"
"push {r0 - r3}"
"mov r0, r3"
"bl dbg_out" - outputs 60000013
"pop {r0 - r3}"
"msr cpsr_fsxc, r2"
"@dsb"
"@isb"
"msr spsr_fsxc, r3" - set value
"@dsb"
"@isb"
"mov lr, r1"
"mov sp, r0"
"push {r0 - r4, lr}"
"mov r0, lr"
"bl dbg_out"
"mov r0, sp"
"bl dbg_out"
"mrs r2, cpsr"
"mrs r3, spsr" - read value
"mov r0, r2"
"bl dbg_out"
"mov r0, r3" - outputs 00000002
"bl dbg_out"
...
);

When the exception is returned from, the calling function:

asm volatile ("svc #0\n\t");

    msg = "returned from SVC\r\n";

    serial_io.put_string(msg, util_str_len(msg)+1);

    asm volatile (

"mrs %[retreg], cpsr\n\t"
:[retreg] "=r" (tmp1) ::

    );

    msg = "cpsr = ";

    serial_io.put_string(msg, util_str_len(msg)+1);

    util_word_to_hex(scratchpad, tmp1);

    serial_io.put_string(scratchpad, 9);

    serial_io.put_string("\r\n", 3);

outputs "returned from SVC" and "cpsr = 60000013".

Why the "00000002"? the barriers don't seem to have any effect.

Parents
  • And another weirdness - this time the gcc:

    The source:

    asm volatile (
    "@ align SP\n\t"
    "mov r0, sp\n\t"
    "and r1, r0, #7\n\t"
    "sub r0, r1\n\t"
    "mov sp, r0\n\t"
    "push {r0,r1} @ stack correction"

        );

        // rpi2_svc_handler2() // - No C in naked function

        asm volatile (

    "mov r0, sp\n\t"
    "mov r1, lr\n\t"
    "push {r0 - r3}\n\t"
    "bl rpi2_svc_handler2\n\t"
    "pop {r0 - r3}\n\t"

        );

        asm volatile (

    "@ restore stack correction"
    "pop {r0, r1}\n\t" - THIS
    "add r0, r1\n\t"
    "mov sp, r0\n\t"

        );

    The disassembly:

    1f000cf8:    e1a0000d     mov    r0, sp

    1f000cfc:    e2001007     and    r1, r0, #7

    1f000d00:    e0400001     sub    r0, r0, r1

    1f000d04:    e1a0d000     mov    sp, r0

    1f000d08:    e92d0003     push    {r0, r1}

    1f000d0c:    e1a0000d     mov    r0, sp

    1f000d10:    e1a0100e     mov    r1, lr

    1f000d14:    e92d000f     push    {r0, r1, r2, r3}

    1f000d18:    ebffff51     bl    1f000a64 <rpi2_svc_handler2>

    1f000d1c:    e8bd000f     pop    {r0, r1, r2, r3}

    Where's the "pop {r0, r1}?

    1f000d20:    e0800001     add    r0, r0, r1

    1f000d24:    e1a0d000     mov    sp, r0

    The stack fix pop in "restore"-part ("pop {r0, r1}\n\t") is missing from the disassembly!

    OK, the push and pop around call to rpi2_svc_handler2 are needless, but still - the stack effect...

    The compiler shouldn't "optimize" such that the stack gets unbalanced, and the data got is wrong.

Reply
  • And another weirdness - this time the gcc:

    The source:

    asm volatile (
    "@ align SP\n\t"
    "mov r0, sp\n\t"
    "and r1, r0, #7\n\t"
    "sub r0, r1\n\t"
    "mov sp, r0\n\t"
    "push {r0,r1} @ stack correction"

        );

        // rpi2_svc_handler2() // - No C in naked function

        asm volatile (

    "mov r0, sp\n\t"
    "mov r1, lr\n\t"
    "push {r0 - r3}\n\t"
    "bl rpi2_svc_handler2\n\t"
    "pop {r0 - r3}\n\t"

        );

        asm volatile (

    "@ restore stack correction"
    "pop {r0, r1}\n\t" - THIS
    "add r0, r1\n\t"
    "mov sp, r0\n\t"

        );

    The disassembly:

    1f000cf8:    e1a0000d     mov    r0, sp

    1f000cfc:    e2001007     and    r1, r0, #7

    1f000d00:    e0400001     sub    r0, r0, r1

    1f000d04:    e1a0d000     mov    sp, r0

    1f000d08:    e92d0003     push    {r0, r1}

    1f000d0c:    e1a0000d     mov    r0, sp

    1f000d10:    e1a0100e     mov    r1, lr

    1f000d14:    e92d000f     push    {r0, r1, r2, r3}

    1f000d18:    ebffff51     bl    1f000a64 <rpi2_svc_handler2>

    1f000d1c:    e8bd000f     pop    {r0, r1, r2, r3}

    Where's the "pop {r0, r1}?

    1f000d20:    e0800001     add    r0, r0, r1

    1f000d24:    e1a0d000     mov    sp, r0

    The stack fix pop in "restore"-part ("pop {r0, r1}\n\t") is missing from the disassembly!

    OK, the push and pop around call to rpi2_svc_handler2 are needless, but still - the stack effect...

    The compiler shouldn't "optimize" such that the stack gets unbalanced, and the data got is wrong.

Children