FAQ
I've been trying to write some ARM assembler to be linked with Go.

I've managed to mostly puzzle out the unusual syntax (unusual to someone
used to ARM's official notation anyway!) with the help of this document,
and squinting at the 5a source code.

http://www.vitanuova.com/inferno/papers/asm.html

However I haven't been able to find the ARM calling convention
documented anywhere. It seems to be that you get all your parameters
passed on the stack and can corrupt any registers except R13 but I'm not
sure about that.

Any pointers on ARM assembly (or indeed any sort of assembly) in Go much
appreciated.

Thanks

Nick
--
Nick Craig-Wood <nick@craig-wood.com> -- http://www.craig-wood.com/nick

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Search Discussions

  • Dave Cheney at Jul 13, 2013 at 12:44 am
    Some waffle about registers in arm.

    R0 to R8 are yours to play with.

    R9 is m R10 is g (see Daniel Morsing's great blog post for an
    explanation). If you overwrite those and you get a signal or a fault,
    then your stack trace will be garbage and/or you will crash the
    runtime.

    R11 belongs to the linker to synthesize instructions, it can be used
    with care, see runtime/memmove_arm.s for example.

    R12 is spare
    R13 is the stack pointer
    R14 is the link register (stores the previous PC)
    R15 is the PC
    On Sat, Jul 13, 2013 at 5:02 AM, Nick Craig-Wood wrote:
    I've been trying to write some ARM assembler to be linked with Go.

    I've managed to mostly puzzle out the unusual syntax (unusual to someone
    used to ARM's official notation anyway!) with the help of this document,
    and squinting at the 5a source code.

    http://www.vitanuova.com/inferno/papers/asm.html

    However I haven't been able to find the ARM calling convention
    documented anywhere. It seems to be that you get all your parameters
    passed on the stack and can corrupt any registers except R13 but I'm not
    sure about that.

    Any pointers on ARM assembly (or indeed any sort of assembly) in Go much
    appreciated.

    Thanks

    Nick
    --
    Nick Craig-Wood <nick@craig-wood.com> -- http://www.craig-wood.com/nick

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Nick Craig-Wood at Jul 13, 2013 at 9:03 am

    On 13/07/13 01:44, Dave Cheney wrote:
    Some waffle about registers in arm.

    R0 to R8 are yours to play with.

    R9 is m R10 is g (see Daniel Morsing's great blog post for an
    explanation). If you overwrite those and you get a signal or a fault,
    then your stack trace will be garbage and/or you will crash the
    runtime.
    Since a signal can come in at any time then I guess R9 and R10 are out
    of bounds unless you disable interrupts.
    R11 belongs to the linker to synthesize instructions, it can be used
    with care, see runtime/memmove_arm.s for example.

    R12 is spare
    R13 is the stack pointer
    R14 is the link register (stores the previous PC)
    R15 is the PC
    Thank you very much for that! With that help I've managed to progress
    from a core dump to a panic to code which runs merely incorrectly ;-)

    I want to use R14/LR as an extra register.

    In order to get the assembler to save it and restore it I seem to have
    to write this. This saves LR at 0(SP) and makes a word of local
    variables at 4(SP).

    TEXT myfn(SB),7,$4

    I was kind of expecting this to save and restore LR without any local
    variables but it doesn't.

    TEXT myfn(SB),7,$0

    As the docs (and some of the code) says this

    // using frame size $-4 means do not save LR on stack.
    TEXT myfn(SB),7,$-4

    Some other parts of the code seem to say if I'm using stack space, I'll
    always get LR at 0(SP), so should put my own stuff at 4(SP) etc - is
    that right?

    While we are talking about stacks, is it OK to push stuff and pop stuff
    from the stack in the middle of a routine? I guess it might mess up the
    assemblers SP and FP but is the runtime OK with that - what if the stack
    needs extending? Does the SP need to be correct at all times?

    Thanks

    Nick
    On Sat, Jul 13, 2013 at 5:02 AM, Nick Craig-Wood wrote:
    I've been trying to write some ARM assembler to be linked with Go.

    I've managed to mostly puzzle out the unusual syntax (unusual to someone
    used to ARM's official notation anyway!) with the help of this document,
    and squinting at the 5a source code.

    http://www.vitanuova.com/inferno/papers/asm.html

    However I haven't been able to find the ARM calling convention
    documented anywhere. It seems to be that you get all your parameters
    passed on the stack and can corrupt any registers except R13 but I'm not
    sure about that.

    Any pointers on ARM assembly (or indeed any sort of assembly) in Go much
    appreciated.

    Thanks

    Nick
    --
    Nick Craig-Wood <nick@craig-wood.com> -- http://www.craig-wood.com/nick

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.

    --
    Nick Craig-Wood <nick@craig-wood.com> -- http://www.craig-wood.com/nick

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Dave Cheney at Jul 13, 2013 at 12:32 pm

    On Sat, Jul 13, 2013 at 7:03 PM, Nick Craig-Wood wrote:
    On 13/07/13 01:44, Dave Cheney wrote:
    Some waffle about registers in arm.

    R0 to R8 are yours to play with.

    R9 is m R10 is g (see Daniel Morsing's great blog post for an
    explanation). If you overwrite those and you get a signal or a fault,
    then your stack trace will be garbage and/or you will crash the
    runtime.
    Since a signal can come in at any time then I guess R9 and R10 are out
    of bounds unless you disable interrupts.
    Pretty much, see also
    https://code.google.com/p/go/issues/detail?id=3718. You can't disable
    interrupts from userspace, and the things you really need to worry
    about, signals, are also non optional.
    R11 belongs to the linker to synthesize instructions, it can be used
    with care, see runtime/memmove_arm.s for example.

    R12 is spare
    R13 is the stack pointer
    R14 is the link register (stores the previous PC)
    R15 is the PC
    Thank you very much for that! With that help I've managed to progress
    from a core dump to a panic to code which runs merely incorrectly ;-)

    I want to use R14/LR as an extra register.
    If you do that then it will upset the traceback mechanism if your
    program panics during execution, or someone hits it with SIGQUIT. This
    may be a cost you are content to live with.
    In order to get the assembler to save it and restore it I seem to have
    to write this. This saves LR at 0(SP) and makes a word of local
    variables at 4(SP).

    TEXT myfn(SB),7,$4

    I was kind of expecting this to save and restore LR without any local
    variables but it doesn't.

    TEXT myfn(SB),7,$0

    As the docs (and some of the code) says this

    // using frame size $-4 means do not save LR on stack.
    TEXT myfn(SB),7,$-4

    Some other parts of the code seem to say if I'm using stack space, I'll
    always get LR at 0(SP), so should put my own stuff at 4(SP) etc - is
    that right?

    While we are talking about stacks, is it OK to push stuff and pop stuff
    from the stack in the middle of a routine? I guess it might mess up the
    assemblers SP and FP but is the runtime OK with that - what if the stack
    needs extending? Does the SP need to be correct at all times?

    Thanks

    Nick
    On Sat, Jul 13, 2013 at 5:02 AM, Nick Craig-Wood wrote:
    I've been trying to write some ARM assembler to be linked with Go.

    I've managed to mostly puzzle out the unusual syntax (unusual to someone
    used to ARM's official notation anyway!) with the help of this document,
    and squinting at the 5a source code.

    http://www.vitanuova.com/inferno/papers/asm.html

    However I haven't been able to find the ARM calling convention
    documented anywhere. It seems to be that you get all your parameters
    passed on the stack and can corrupt any registers except R13 but I'm not
    sure about that.

    Any pointers on ARM assembly (or indeed any sort of assembly) in Go much
    appreciated.

    Thanks

    Nick
    --
    Nick Craig-Wood <nick@craig-wood.com> -- http://www.craig-wood.com/nick

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.

    --
    Nick Craig-Wood <nick@craig-wood.com> -- http://www.craig-wood.com/nick
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Minux at Jul 14, 2013 at 5:53 pm

    On Sat, Jul 13, 2013 at 5:03 PM, Nick Craig-Wood wrote:
    On 13/07/13 01:44, Dave Cheney wrote:
    Some waffle about registers in arm.

    R0 to R8 are yours to play with.

    R9 is m R10 is g (see Daniel Morsing's great blog post for an
    explanation). If you overwrite those and you get a signal or a fault,
    then your stack trace will be garbage and/or you will crash the
    runtime.
    Since a signal can come in at any time then I guess R9 and R10 are out
    of bounds unless you disable interrupts.
    R11 belongs to the linker to synthesize instructions, it can be used
    with care, see runtime/memmove_arm.s for example.

    R12 is spare
    R13 is the stack pointer
    R14 is the link register (stores the previous PC)
    R15 is the PC
    Thank you very much for that! With that help I've managed to progress
    from a core dump to a panic to code which runs merely incorrectly ;-)

    I want to use R14/LR as an extra register.
    it's ok, but you need to make sure the last number in TEXT line is 0 or more
    so that LR will be saved at function entry.
    In order to get the assembler to save it and restore it I seem to have
    to write this. This saves LR at 0(SP) and makes a word of local
    variables at 4(SP).
    i suggest you access the first argument as 0(FP) instead of 4(R13), it might
    find the latter forms in the source code, but it's not recommended.

    as 0(FP) will always work.
    TEXT myfn(SB),7,$4

    I was kind of expecting this to save and restore LR without any local
    variables but it doesn't.
    the linker is smart about saving and restoring LR. if it determined that
    your function
    doesn't call another function via BL, it will regard it as a leaf function,
    so it won't
    save LR.
    you could call a dummy function to force the save of LR or, you can
    save/restore
    LR yourself.
    TEXT myfn(SB),7,$0

    As the docs (and some of the code) says this

    // using frame size $-4 means do not save LR on stack.
    TEXT myfn(SB),7,$-4

    Some other parts of the code seem to say if I'm using stack space, I'll
    always get LR at 0(SP), so should put my own stuff at 4(SP) etc - is
    that right?

    While we are talking about stacks, is it OK to push stuff and pop stuff
    from the stack in the middle of a routine? I guess it might mess up the
    assemblers SP and FP but is the runtime OK with that - what if the stack
    needs extending? Does the SP need to be correct at all times?
    it's ok, just make sure you've balanced the stack before RET.
    the SP needs only be correct if you use DIV/MOD (as these are synthesized
    instruction by the linker, and might use the stack) or call another
    function.

    yes, the linker will calculate static offset for x(FP) or y(SP), so be sure
    you've
    compensated the offset if you adjusted R13.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Nick Craig-Wood at Jul 14, 2013 at 7:45 pm

    On 14/07/13 18:52, minux wrote:

    On Sat, Jul 13, 2013 at 5:03 PM, Nick Craig-Wood wrote:
    I want to use R14/LR as an extra register.

    it's ok, but you need to make sure the last number in TEXT line is 0 or more
    so that LR will be saved at function entry.

    In order to get the assembler to save it and restore it I seem to have
    to write this. This saves LR at 0(SP) and makes a word of local
    variables at 4(SP).

    i suggest you access the first argument as 0(FP) instead of 4(R13), it might
    find the latter forms in the source code, but it's not recommended.
    as 0(FP) will always work.
    There is something I'm not clear about here...

    0(FP) works very well for accessing the arguments, however I'm having
    difficulty accessing the local stack variables.

    According to the documentation here

    http://www.vitanuova.com/inferno/papers/asm.html

    The first automatic variable should be at 4(SP). However that seems to
    refer to the same memory location as 4(FP) which is confusing! What
    does appear to work is using 4(R13) for accessing local variables.

    Is that correct?

    Thanks very much for your explanations - that has cleared up a lot of
    things!

    --
    Nick Craig-Wood <nick@craig-wood.com> -- http://www.craig-wood.com/nick

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Brainman at Jul 15, 2013 at 12:00 am

    On Monday, 15 July 2013 05:45:48 UTC+10, Nick Craig-Wood wrote:

    The first automatic variable should be at 4(SP). However that seems to
    refer to the same memory location as 4(FP) which is confusing! ...
    I am no good with asm, but this is how I understand it.

    When function gets called, its parameters go to the stack first. Last
    parameter goes first, first parameter last - FP is set to SP (so it will be
    pointing to first parameter from now on). Then call is made - this inserts
    return address into stack, so now first parameter can be accessed as 4(SP)
    (on 386), but in asm it can still be referred to as 0(FP). So, if you have
    no local variables, then 4(SP) is equal to 0(FP) (on 386).

    If you need some local variables, you should say how much. For example
    https://code.google.com/p/go/source/browse/src/pkg/runtime/asm_386.s#503

    TEXT runtime·cgocallback(SB),7,$12

    uses 3 local variables (4 bytes each) - 3*4=12, and you can refer to these
    as 0(SP), 4(SP) and 8(SP). Even here you can refer to your first function
    parameter as 0(FP).

    Alex

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Minux at Jul 15, 2013 at 6:58 am

    On Mon, Jul 15, 2013 at 3:45 AM, Nick Craig-Wood wrote:

    There is something I'm not clear about here...

    0(FP) works very well for accessing the arguments, however I'm having
    difficulty accessing the local stack variables.

    According to the documentation here

    http://www.vitanuova.com/inferno/papers/asm.html

    The first automatic variable should be at 4(SP). However that seems to
    refer to the same memory location as 4(FP) which is confusing! What
    does appear to work is using 4(R13) for accessing local variables.

    Is that correct?
    correct. 5l is different in this respect from other linkers (8l/6l) where
    0(SP)
    do refer to the local variable with the lowest address.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Nick Craig-Wood at Jul 20, 2013 at 8:37 am

    On 15/07/13 07:58, minux wrote:
    On Mon, Jul 15, 2013 at 3:45 AM, Nick Craig-Wood wrote:

    0(FP) works very well for accessing the arguments, however I'm having
    difficulty accessing the local stack variables.

    According to the documentation here

    http://www.vitanuova.com/inferno/papers/asm.html

    The first automatic variable should be at 4(SP). However that seems to
    refer to the same memory location as 4(FP) which is confusing! What
    does appear to work is using 4(R13) for accessing local variables.

    Is that correct?

    correct. 5l is different in this respect from other linkers (8l/6l)
    where 0(SP)
    do refer to the local variable with the lowest address.
    I've come to the conclusion that that is probably a bug! If FP == SP
    then it breaks the assumptions of assembly code writers by making ARM
    different and makes the assembler less convenient to use because the
    variable+4(R13) form isn't allowed.

    Here is an example from ./pkg/runtime/memmove_arm.s which is only
    working by good luck!

    TEXT runtime·memmove(SB), 7, $4-12
    _memmove:
             MOVW to+0(FP), R(TS)
             MOVW from+4(FP), R(FROM)
             MOVW n+8(FP), R(N)

    [snip]

    _b4aligned: /* is source now aligned? */
             AND.S $3, R(FROM), R(TMP)
             BNE _bunaligned

             ADD $31, R(TS), R(TMP) /* do 32-byte chunks if possible */
             MOVW R(TS), savedts+4(SP) // <------ THIS IS WRONG!
    _b32loop:
             CMP R(TMP), R(TE)
             BLS _b4tail

    Which disassembles to

    0003a370 <runtime.memmove>:
        3a370: e52de008 str r14, [r13, #-8]!
        3a374: e59d000c ldr r0, [r13, #12] // to argument
        3a378: e59db010 ldr r11, [r13, #16]
        3a37c: e59dc014 ldr r12, [r13, #20]

    [snip]

        3a3b0: e21bc003 ands r12, r11, #3
        3a3b4: 1a000015 bne 3a410 <runtime.memmove+0xa0>
        3a3b8: e280c01f add r12, r0, #31
        3a3bc: e58d000c str r0, [r13, #12] // should be #4
        3a3c0: e158000c cmp r8, r12
        3a3c4: 9a000002 bls 3a3d4 <runtime.memmove+0x64>

    It was clearly the intention of the author to save R(TS) in the stack
    frame (otherwise why allocate it) but actually it is being saved in the
    to argument. In fact the allocated word in the stack frame 4(R13) is
    never used.

    This could be corrected by changing it to this (can't use savedts+ on
    (R13) for some reason which is another argument for fixing SP)

             MOVW R(TS), 4(R13)

    The ARM code seems to use FP and SP interchangeably so a lot of code
    would need to be reviewed if this were to be changed.

    Anyway if we are stuck with FP == SP then memmove surely needs to be fixed!

    --
    Nick Craig-Wood <nick@craig-wood.com> -- http://www.craig-wood.com/nick

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Dave Cheney at Jul 20, 2013 at 8:57 am
    I am the author, this was my fault.

    Please log an issue and if your able propose a fix, if we're quick it might make it into 1.1.2.

    Thanks

    Dave
    On 20/07/2013, at 18:37, Nick Craig-Wood wrote:
    On 15/07/13 07:58, minux wrote:
    On Mon, Jul 15, 2013 at 3:45 AM, Nick Craig-Wood <nick@craig-wood.com
    wrote:

    0(FP) works very well for accessing the arguments, however I'm having
    difficulty accessing the local stack variables.

    According to the documentation here

    http://www.vitanuova.com/inferno/papers/asm.html

    The first automatic variable should be at 4(SP). However that seems to
    refer to the same memory location as 4(FP) which is confusing! What
    does appear to work is using 4(R13) for accessing local variables.

    Is that correct?

    correct. 5l is different in this respect from other linkers (8l/6l)
    where 0(SP)
    do refer to the local variable with the lowest address.
    I've come to the conclusion that that is probably a bug! If FP == SP
    then it breaks the assumptions of assembly code writers by making ARM
    different and makes the assembler less convenient to use because the
    variable+4(R13) form isn't allowed.

    Here is an example from ./pkg/runtime/memmove_arm.s which is only
    working by good luck!

    TEXT runtime·memmove(SB), 7, $4-12
    _memmove:
    MOVW to+0(FP), R(TS)
    MOVW from+4(FP), R(FROM)
    MOVW n+8(FP), R(N)

    [snip]

    _b4aligned: /* is source now aligned? */
    AND.S $3, R(FROM), R(TMP)
    BNE _bunaligned

    ADD $31, R(TS), R(TMP) /* do 32-byte chunks if possible */
    MOVW R(TS), savedts+4(SP) // <------ THIS IS WRONG!
    _b32loop:
    CMP R(TMP), R(TE)
    BLS _b4tail

    Which disassembles to

    0003a370 <runtime.memmove>:
    3a370: e52de008 str r14, [r13, #-8]!
    3a374: e59d000c ldr r0, [r13, #12] // to argument
    3a378: e59db010 ldr r11, [r13, #16]
    3a37c: e59dc014 ldr r12, [r13, #20]

    [snip]

    3a3b0: e21bc003 ands r12, r11, #3
    3a3b4: 1a000015 bne 3a410 <runtime.memmove+0xa0>
    3a3b8: e280c01f add r12, r0, #31
    3a3bc: e58d000c str r0, [r13, #12] // should be #4
    3a3c0: e158000c cmp r8, r12
    3a3c4: 9a000002 bls 3a3d4 <runtime.memmove+0x64>

    It was clearly the intention of the author to save R(TS) in the stack
    frame (otherwise why allocate it) but actually it is being saved in the
    to argument. In fact the allocated word in the stack frame 4(R13) is
    never used.

    This could be corrected by changing it to this (can't use savedts+ on
    (R13) for some reason which is another argument for fixing SP)

    MOVW R(TS), 4(R13)

    The ARM code seems to use FP and SP interchangeably so a lot of code
    would need to be reviewed if this were to be changed.

    Anyway if we are stuck with FP == SP then memmove surely needs to be fixed!

    --
    Nick Craig-Wood <nick@craig-wood.com> -- http://www.craig-wood.com/nick
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Nick Craig-Wood at Jul 21, 2013 at 7:39 am

    On 20/07/13 09:56, Dave Cheney wrote:
    I am the author, this was my fault.

    Please log an issue and if your able propose a fix, if we're quick it might make it into 1.1.2.
    I have made an issue and proposed a fix

    https://code.google.com/p/go/issues/detail?id=5925

    https://codereview.appspot.com/11647043

    I'd still like to have a discussion on whether we should fix SP vs FP
    though!
    On 20/07/2013, at 18:37, Nick Craig-Wood wrote:
    On 15/07/13 07:58, minux wrote:
    On Mon, Jul 15, 2013 at 3:45 AM, Nick Craig-Wood <nick@craig-wood.com
    wrote:

    0(FP) works very well for accessing the arguments, however I'm having
    difficulty accessing the local stack variables.

    According to the documentation here

    http://www.vitanuova.com/inferno/papers/asm.html

    The first automatic variable should be at 4(SP). However that seems to
    refer to the same memory location as 4(FP) which is confusing! What
    does appear to work is using 4(R13) for accessing local variables.

    Is that correct?

    correct. 5l is different in this respect from other linkers (8l/6l)
    where 0(SP)
    do refer to the local variable with the lowest address.
    I've come to the conclusion that that is probably a bug! If FP == SP
    then it breaks the assumptions of assembly code writers by making ARM
    different and makes the assembler less convenient to use because the
    variable+4(R13) form isn't allowed.

    Here is an example from ./pkg/runtime/memmove_arm.s which is only
    working by good luck!

    TEXT runtime·memmove(SB), 7, $4-12
    _memmove:
    MOVW to+0(FP), R(TS)
    MOVW from+4(FP), R(FROM)
    MOVW n+8(FP), R(N)

    [snip]

    _b4aligned: /* is source now aligned? */
    AND.S $3, R(FROM), R(TMP)
    BNE _bunaligned

    ADD $31, R(TS), R(TMP) /* do 32-byte chunks if possible */
    MOVW R(TS), savedts+4(SP) // <------ THIS IS WRONG!
    _b32loop:
    CMP R(TMP), R(TE)
    BLS _b4tail

    Which disassembles to

    0003a370 <runtime.memmove>:
    3a370: e52de008 str r14, [r13, #-8]!
    3a374: e59d000c ldr r0, [r13, #12] // to argument
    3a378: e59db010 ldr r11, [r13, #16]
    3a37c: e59dc014 ldr r12, [r13, #20]

    [snip]

    3a3b0: e21bc003 ands r12, r11, #3
    3a3b4: 1a000015 bne 3a410 <runtime.memmove+0xa0>
    3a3b8: e280c01f add r12, r0, #31
    3a3bc: e58d000c str r0, [r13, #12] // should be #4
    3a3c0: e158000c cmp r8, r12
    3a3c4: 9a000002 bls 3a3d4 <runtime.memmove+0x64>

    It was clearly the intention of the author to save R(TS) in the stack
    frame (otherwise why allocate it) but actually it is being saved in the
    to argument. In fact the allocated word in the stack frame 4(R13) is
    never used.

    This could be corrected by changing it to this (can't use savedts+ on
    (R13) for some reason which is another argument for fixing SP)

    MOVW R(TS), 4(R13)

    The ARM code seems to use FP and SP interchangeably so a lot of code
    would need to be reviewed if this were to be changed.

    Anyway if we are stuck with FP == SP then memmove surely needs to be fixed!

    --
    Nick Craig-Wood <nick@craig-wood.com> -- http://www.craig-wood.com/nick

    --
    Nick Craig-Wood <nick@craig-wood.com> -- http://www.craig-wood.com/nick

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Dmitry Vyukov at Jul 15, 2013 at 1:20 pm

    On Sat, Jul 13, 2013 at 1:03 PM, Nick Craig-Wood wrote:
    While we are talking about stacks, is it OK to push stuff and pop stuff
    from the stack in the middle of a routine? I guess it might mess up the
    assemblers SP and FP but is the runtime OK with that - what if the stack
    needs extending? Does the SP need to be correct at all times?
    Yes, stack needs to be correct at all times. This is required for CPU
    profiling and GC. Runtime needs to be able to determine stack frames
    at all times.
    This is *not* implemented in runtime yet
    (https://code.google.com/p/go/issues/detail?id=5736). But when it is
    implemented runtime will need to understand stack frame managing code.
    I would suggest sticking with the code that is generated by 6g/6c or
    runtime assembly.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Jan Mercl at Jul 13, 2013 at 12:54 pm

    On Sat, Jul 13, 2013 at 2:44 AM, Dave Cheney wrote:
    (see Daniel Morsing's great blog post for an
    explanation).
    FTR: http://morsmachine.dk/go-scheduler

    -j

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedJul 12, '13 at 7:02p
activeJul 21, '13 at 7:39a
posts13
users6
websitegolang.org

People

Translate

site design / logo © 2022 Grokbase